FTP Download

     最近要完成WPF程序的自动升级功能,自动升级的思路请见圣殿骑士WPF企业内训全程实录(下)中的部署与自动更新 部分。其中就需要连接到FTP服务器进行文件的下载,查阅了 All-In-One Code FrameworkCSFTPDownload 例子和微软的帮助文档。其中主要代码引用自CSFTPDownload和微软官方示例。详情请自己查阅微软官方MSDN,最好是安装到自己的电脑上,查阅起来方便,具体操作方法请参见英文VS2010安装中文版MSDN文档方法VS2010帮助查看器推荐两片文章。

      这里使用 System.Net.FtpWebRequest 类通过编程的方式与FTP服务器进行交互。另外还可以使用 System.Net.WebClient 类来进行操作。

直接上代码,代码是可用的,经过测试通过的。

 

public class FTPHelper
    {
        public FTPHelper(NetworkCredential credentials)
        {
            this.Credentials = credentials;
        }

        #region Fields

        // 2M bytes.
        public const int MaxCacheSize = 2097152;

        // 2K bytes.
        public const int BufferSize = 2048;

        public NetworkCredential Credentials { get; set; }

        #endregion Fields

        #region Public Methods

        /// <summary>
        /// Download file. FTP Uri eg.ftp://localhost/TestDiretory/ (In this,Last '/' must be include)
        /// </summary>
        /// <param name="urlStr"></param>
        /// <param name="fileName"></param>
        /// <param name="savePath"></param>
        public  void DownloadFile(string urlStr, string fileName,string savePath)
        {

            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(urlStr + fileName);
            request.Method = WebRequestMethods.Ftp.DownloadFile;

            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }

            string destPath = Path.Combine(savePath, fileName);

            request.Credentials = Credentials;

            FtpWebResponse response = null;
            Stream responseStream = null;
            MemoryStream downloadCache = null;

            try
            {
                response = (FtpWebResponse)request.GetResponse();

                responseStream = response.GetResponseStream();

                StreamReader reader = new StreamReader(responseStream);

                // Cache data in memory.
                downloadCache = new MemoryStream(MaxCacheSize);
                byte[] downloadBuffer = new byte[BufferSize];

                int bytesSize = 0;
                int cachedSize = 0;

                // Download the file until the download is completed.
                while (true)
                {

                    // Read a buffer of data from the stream.
                    bytesSize = responseStream.Read(downloadBuffer, 0,
                        downloadBuffer.Length);

                    // If the cache is full, or the download is completed, write 
                    // the data in cache to local file.
                    if (bytesSize == 0
                        || MaxCacheSize < cachedSize + bytesSize)
                    {
                        try
                        {
                            // Write the data in cache to local file.
                            WriteCacheToFile(downloadCache, destPath, cachedSize);

                            // Stop downloading the file if the download is paused, 
                            // canceled or completed. 
                            if (bytesSize == 0)
                            {
                                break;
                            }

                            // Reset cache.
                            downloadCache.Seek(0, SeekOrigin.Begin);
                            cachedSize = 0;
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }

                    }

                    // Write the data from the buffer to the cache in memory.
                    downloadCache.Write(downloadBuffer, 0, bytesSize);
                    cachedSize += bytesSize;
                }
            }catch(Exception ex)
            {
                throw new Exception("下?载?文?件t失§败ü!?",ex);
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }

                if (responseStream != null)
                {
                    responseStream.Close();
                }

                if (downloadCache != null)
                {
                    downloadCache.Close();
                }
            }
        }



        #endregion Public Methods

        #region Private Methods

        /// <summary>
        /// Write the data in cache to local file.
        /// </summary>
        private void WriteCacheToFile(MemoryStream downloadCache, string downloadPath,
            int cachedSize)
        {
            using (FileStream fileStream = new FileStream(downloadPath,
                FileMode.Create))
            {
                byte[] cacheContent = new byte[cachedSize];
                downloadCache.Seek(0, SeekOrigin.Begin);
                downloadCache.Read(cacheContent, 0, cachedSize);
                fileStream.Write(cacheContent, 0, cachedSize);
            }
        }

        #endregion Private Methods

    }
posted @ 2011-07-08 16:46  糊涂而已  阅读(743)  评论(0编辑  收藏  举报