FtpWebRequest FTP异步下载、异步上传文件

异步下载:

public interface IPrimaryKey<T>

    {

        T GetKey();

    }



    public class DownloadInfo : IPrimaryKey<string>

    {

        public string FtpResourceFilePath { get; set; }



        public string FileSaveLocalPath { get; set; }



        public bool IsDir { get; set; }



        public DateTime StartTime { get; set; }



        public int ProgressPercentage { get; set; }



        public string Speed { get; set; }



        public string GetKey()

        {

            return this.FtpResourceFilePath;

        }



        public List<DownloadInfo> SubFiles { get; set; }

    }
    class Program

    {

        static readonly string FTP_USERNAME = string.Empty;

        static readonly string FTP_PASSWORD = string.Empty;

        static readonly string FTP_DOMAIN = string.Empty;

        // default 1 seconds.

        static readonly int FTP_REQUEST_TIMEOUT = 1;

        // default 1 seconds.

        static readonly int FTP_REQUEST_READWRITERTIMEOUT = 1;



        static Program()

        {

            FTP_REQUEST_TIMEOUT = Convert.ToInt32(ConfigurationManager.AppSettings.Get("FTP.Request.Timeout"));

            FTP_REQUEST_READWRITERTIMEOUT = Convert.ToInt32(ConfigurationManager.AppSettings.Get("FTP.Request.ReadWriteTimeout"));

            FTP_USERNAME = ConfigurationManager.AppSettings.Get("FTP.UserName");

            FTP_PASSWORD = ConfigurationManager.AppSettings.Get("FTP.Password");

            FTP_DOMAIN = ConfigurationManager.AppSettings.Get("FTP.Domain");

        }



        static int DownloadCount = 0;

        static int CompleteCount = 0;



        static void Main(string[] args)

        {

            // default max parallel connection count is two in the .net framework.

            // sugesstion no over 1024.

            // and you also can add config node in app.config

            /* <configuration>

             *  <system.net>

             *      <connectionManagement>

             *          <add address="*" maxconnection="512"/>

             *      </connectionManagement>

             *  </system>

             * </configuration>

             */

            //System.Net.ServicePointManager.DefaultConnectionLimit = 512;



            string localRootPath = ConfigurationManager.AppSettings.Get("SaveRootPath");



            List<DownloadInfo> rootFiles = GetSubFilesList(new DownloadInfo()

            {

                FtpResourceFilePath = "ftp://172.21.3.17//dd/MR",

                FileSaveLocalPath = string.Concat(localRootPath, "~TEMP\\Test1")

            });



            DownloadFilesAsync(rootFiles);



            Console.ReadKey();

        }



        private static void DownloadFilesAsync(List<DownloadInfo> items)

        {

            foreach (DownloadInfo task in items)

            {

                task.StartTime = DateTime.Now;



                if (task.IsDir)

                {

                    task.SubFiles = GetSubFilesList(task);



                    DownloadFilesAsync(task.SubFiles);

                }

                else

                {

                    // try create the directory before donwload.

                    TryCreateDirectory(task.FileSaveLocalPath);



                    // Uri      :the resource paht which will be download.

                    // fileName :the dowload file save path;

                    CreateWebClient().DownloadFileAsync(new Uri(task.FtpResourceFilePath), task.FileSaveLocalPath, task);

                }

            }

        }



        static WebClient CreateWebClient()

        {

        // 限制最多同时现在的线程数

        LimitThreadAgain:

            if (DownloadCount - CompleteCount > 300)

            {

                Thread.Sleep(5000);



                goto LimitThreadAgain;

            }



            DownloadCount++;



            WebClient client = new WebClient();

            client.Credentials = new NetworkCredential(FTP_USERNAME, FTP_PASSWORD, FTP_DOMAIN);

            client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);

            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);



            return client;

        }



        private static List<DownloadInfo> GetSubFilesList(DownloadInfo task)

        {

            List<DownloadInfo> subFiles = new List<DownloadInfo>();



            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(task.FtpResourceFilePath));

            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

            request.Credentials = new NetworkCredential(FTP_USERNAME, FTP_PASSWORD, FTP_DOMAIN);

            request.UseBinary = true;

            request.Timeout = FTP_REQUEST_TIMEOUT;

            request.ReadWriteTimeout = FTP_REQUEST_READWRITERTIMEOUT;



            using (WebResponse response = request.GetResponse())

            {

                using (StreamReader responseStream = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default))

                {

                    string line = responseStream.ReadLine();

                    while (line != null)

                    {

                        Console.WriteLine(line);



                        string[] lineParitialArray = line.Split(new char[] { ' ' });

                        string theName = lineParitialArray[lineParitialArray.Length - 1];



                        if (line.IndexOf("<DIR>") != -1)

                        {

                            subFiles.Add(new DownloadInfo()

                            {

                                FtpResourceFilePath = string.Concat(task.FtpResourceFilePath, "/", theName),

                                FileSaveLocalPath = string.Concat(task.FileSaveLocalPath, "\\", theName),

                                IsDir = true

                            });

                        }

                        else

                        {

                            subFiles.Add(new DownloadInfo()

                            {

                                FtpResourceFilePath = string.Concat(task.FtpResourceFilePath, "/", theName),

                                FileSaveLocalPath = string.Concat(task.FileSaveLocalPath, "\\", theName),

                                IsDir = false

                            });

                        }



                        line = responseStream.ReadLine();

                    }

                }

            }



            return subFiles;

        }



        static void TryCreateDirectory(string filePath)

        {

            FileInfo fileInfo = new FileInfo(filePath);

            if (!fileInfo.Directory.Exists)

            {

                try

                {

                    fileInfo.Directory.Create();

                }

                catch (Exception ex)

                {

                    Logger.Current.Error("an error thrown while create directory:\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);

                }

            }

        }



        static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

        {

            DownloadInfo downloadInfo = e.UserState as DownloadInfo;



            downloadInfo.ProgressPercentage = e.ProgressPercentage;

            double downloadTime = (DateTime.Now - downloadInfo.StartTime).TotalSeconds;

            downloadInfo.Speed = GetFriendlyFileSize(e.BytesReceived / downloadTime, 2);



            Console.WriteLine("download precentage:{0}-{1}-{2}", downloadInfo.ProgressPercentage, downloadInfo.Speed, downloadInfo.FtpResourceFilePath);



            Logger.Current.Debug(string.Format("download precentage:{0}-{1}-{2}", downloadInfo.ProgressPercentage, downloadInfo.Speed, downloadInfo.FtpResourceFilePath));

        }



        static void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

        {

            if (e.Error != null)

            {

                if (e.Error.InnerException != null)

                    Logger.Current.Error(string.Format("download error:{0}\r\n{1}", e.Error.InnerException.Message, e.Error.InnerException.StackTrace));

                else

                    Logger.Current.Error(string.Format("download error:{0}\r\n{1}", e.Error.Message, e.Error.StackTrace));

            }



            DownloadInfo downloadInfo = e.UserState as DownloadInfo;



            Console.WriteLine("download complete:{0}", downloadInfo.FtpResourceFilePath);

            Logger.Current.Debug(string.Format("download complete:{0}", downloadInfo.FtpResourceFilePath));



            CompleteCount++;

        }



        const double KB = 1024;

        const double MR = KB * 1024;

        const double GB = MR * 1024;

        const double TB = MR * 1024;

        const double PB = TB * 1024;



        static string GetFriendlyFileSize(double size, int decimals)

        {

            if (KB > size)

                return string.Format("{0}B", Math.Round(size, decimals));

            else if (MR > size)

                return string.Format("{0}KB", Math.Round(size / KB, decimals));

            else if (GB > size)

                return string.Format("{0}MR", Math.Round(size / MR, decimals));

            else if (TB > size)

                return string.Format("{0}GB", Math.Round(size / GB, decimals));

            else if (PB > size)

                return string.Format("{0}TB", Math.Round(size / TB, decimals));

            else

                return string.Format("{0}PB", Math.Round(size / PB, decimals));

        }

}

 

异步上传:

// uploading

#region uploading



public class Program

{

    public static void Main(string[] args)

    {

        FtpState state = new FtpState();



        // the ftp url scheme like: ftp://

        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://172.21.*.1*//dd/SHFBGuidedInstaller_2014.5.31.0.zip"));

        request.Method = WebRequestMethods.Ftp.UploadFile;

        //request.Method = WebRequestMethods.Ftp.DownloadFile;



        request.Credentials = new NetworkCredential("dn", "new.1234", "domain");



        state.Request = request;

        state.FileName = @"C:\Users\dn\Desktop\SHFBGuidedInstaller_2014.5.31.0.zip";

        //state.FileName = @"C:\Users\dn\Desktop\MR\SHFBGuidedInstaller_2014.5.31.0.zip";



        // 获得WaitOne()对象

        ManualResetEvent waitOjbect = state.OperationComplete;



        // 开始异步获取数据流

        request.BeginGetRequestStream(

            new AsyncCallback(EndGetStreamCallback),

            state

            );



        // 线程等待

        waitOjbect.WaitOne();



        if (state.OperationException != null)

        {

            throw state.OperationException;

        }

        else

        {

            Console.WriteLine("操作已经完成!");

        }

   }



       public class FtpState

       {

            private ManualResetEvent wait;

            private FtpWebRequest request;

            private string fileName;

            private Exception opreationException = null;

            private string statusDescription;



            public FtpState()

            {

                wait = new ManualResetEvent(false);

            }



            public ManualResetEvent OperationComplete

            {

                get { return wait; }

            }



            public FtpWebRequest Request

            {

                get { return request; }

                set { request = value; }

            }



            public string FileName

            {

                get { return fileName; }

                set { fileName = value; }

            }



            public Exception OperationException

            {

                get { return opreationException; }

                set { opreationException = value; }

            }



            public string StatusDescription

            {

                get { return statusDescription; }

                set { statusDescription = value; }

            }

        }



        private static void EndGetStreamCallback(IAsyncResult result)

        {

            FtpState state = (FtpState)result.AsyncState;



            try

            {

                using (Stream requestStream = state.Request.EndGetRequestStream(result))

                {

                    const int bufferLength = 2048;

                    byte[] buffer = new byte[bufferLength];



                    int count = 0;

                    int readBytes = 0;



                    using (FileStream stream = File.OpenRead(state.FileName))

                    {

                        do

                        {

                            readBytes = stream.Read(buffer, 0, bufferLength);



                            requestStream.Write(buffer, 0, readBytes);



                            count += readBytes;

                        }

                        while (readBytes != 0);

                    }



                    Console.WriteLine("写入{0}字节到数据流中", count);



                    state.Request.BeginGetResponse(new AsyncCallback(EndGetResponseCallback), state);

                }

            }

            catch (Exception ex)

            {

                Console.WriteLine("请求数据流失败!");



                state.OperationException = ex;

                state.OperationComplete.Set();

            }

        }



        private static void EndGetResponseCallback(IAsyncResult result)

        {

            FtpState state = (FtpState)result.AsyncState;



            try

            {

                FtpWebResponse response = (FtpWebResponse)state.Request.EndGetResponse(result);

                response.Close();



                state.StatusDescription = response.StatusDescription;

                // 标记主线程结束

                state.OperationComplete.Set();

            }

            catch (Exception ex)

            {

                Console.WriteLine("获取请求回应失败!");

                state.OperationException = ex;

                state.OperationComplete.Set();

            }

        }



        #endregion

}

 

你可能感兴趣的:(request)