zoukankan      html  css  js  c++  java
  • 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:
    {0}
    {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}
    {1}", e.Error.InnerException.Message, e.Error.InnerException.StackTrace));
                    else
                        Logger.Current.Error(string.Format("download error:{0}
    {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:UsersdnDesktopSHFBGuidedInstaller_2014.5.31.0.zip";
            //state.FileName = @"C:UsersdnDesktopMRSHFBGuidedInstaller_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
    }
  • 相关阅读:
    The Quad
    将OrCAD Capture CIS的设计文件(.dsn)导入到PADS Logic VX.2.3
    OrCAD Capture CIS 16.6 将版本16.6的设计文件另存为版本16.2的设计文件
    Eclipse IDE 添加jar包到Java工程中
    PADS Logic VX.2.3 修改软件界面语言
    切换Allegro PCB Editor
    Allegro PCB Design GXL (legacy) 将brd文件另存为低版本文件
    Allegro PCB Design GXL (legacy) 设置自动保存brd文件
    Could not create an acl object: Role '16'
    windows 下apache开启FastCGI
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/4629335.html
Copyright © 2011-2022 走看看