FTP Download
最近要完成WPF程序的自动升级功能,自动升级的思路请见圣殿骑士的WPF企业内训全程实录(下)中的部署与自动更新 部分。其中就需要连接到FTP服务器进行文件的下载,查阅了 All-In-One Code Framework 的 CSFTPDownload 例子和微软的帮助文档。其中主要代码引用自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 }