包装FTPWebRequest类

上篇文章讨论了C#从基于FTPS的FTP server下载数据 (FtpWebRequest 的使用)SSL 加密不过细心的朋友应该可以发现FTPWebRequest 每次都是新生成一个request ( FTPWebRequest.create(uri) ), 这样对于一些复杂的需求,需要反复登陆,代码就会变得冗余啰嗦,那今天就和大家探讨一下如何包装FTPWebRequest类。如有好的想法或意见,希望各位大神老鸟多多指教。

 
先说一下我的需求:
 
去FTP Server 的一个指定路径下,找到更新时间最近的文件并下载。
那按照以上需求,就需要先去路径下,找到更新时间最近的文件,在根据文件名下载。 
 
这里封装一个FTPClient 类 (从网上找了一个FTPClient的壳子,忘记了原博客地址了,抱歉)
原理很简单,就是封装‘列出目录功能’和 ‘下载文件功能’。将用户名密码等放在FTPClient的属性中。
上码!
 
  1 using System.Collections.Generic;
  2 using System;
  3 using System.Net;
  4 using System.IO;
  5 using System.Security.Cryptography.X509Certificates;
  6 using System.Net.Security;
  7 
  8 namespace FtpClientBlogCase
  9 {
 10 
 11 
 12     #region "FTP client class"
 13     public class FTPclient
 14     {
 15         #region "CONSTRUCTORS"
 16         public FTPclient(string Hostname, string Username, string Password, bool EnableSSL)
 17         {
 18             this.Hostname = Hostname;
 19             this.Username = Username;
 20             this.Password = Password;
 21             this.EnableSsl = EnableSSL;
 22         }
 23         #endregion
 24 
 25         #region "Directory functions"
 26         public List<string> ListDirectory(string URI)
 27         {
 28             System.Net.FtpWebRequest ftp = GetRequest(URI);
 29             //Set request to do simple list
 30             ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectory;
 31 
 32             string str = GetStringResponse(ftp);
 33             //replace CRLF to CR, remove last instance
 34             str = str.Replace("\r\n", "\r").TrimEnd('\r');
 35             //split the string into a list
 36             List<string> result = new List<string>();
 37             result.AddRange(str.Split('\r'));
 38             return result;
 39         }
 40         #endregion
 41 
 42         #region "Download: File transfer FROM ftp server"
 43         /// <summary>
 44         /// Copy a file from FTP server to local
 45         /// </summary>
 46         /// <param name="sourceFilename">Target filename, if required</param>
 47         /// <param name="localFilename">Full path of the local file</param>
 48         /// <returns></returns>
 49         /// <remarks>
 50         /// Target can be blank (use same filename), or just a filename
 51         /// (assumes current directory) or a full path and filename
 52         /// 1.2 [HR] added CreateURI
 53         /// </remarks>
 54         public bool Download(string sourceFilename, string localFilename, bool PermitOverwrite)
 55         {
 56             //2. determine target file
 57             FileInfo fi = new FileInfo(localFilename);
 58             return this.Download(sourceFilename, fi, PermitOverwrite);
 59         }
 60 
 61         /// <summary>
 62         /// Version taking string/FileInfo
 63         /// </summary>
 64         /// <param name="sourceFilename"></param>
 65         /// <param name="targetFI"></param>
 66         /// <param name="PermitOverwrite"></param>
 67         /// <returns></returns>
 68         public bool Download(string sourceFilename, FileInfo targetFI, bool PermitOverwrite)
 69         {
 70             //1. check target
 71             if (targetFI.Exists && !(PermitOverwrite))
 72             {
 73                 throw (new ApplicationException("Target file already exists"));
 74             }
 75 
 76             //2. check source
 77             if (String.IsNullOrEmpty(sourceFilename))
 78             {
 79                 throw (new ApplicationException("File not specified"));
 80             }
 81             System.Net.FtpWebRequest ftp = GetRequest(sourceFilename);
 82 
 83             //Set request to download a file in binary mode
 84             ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
 85             ftp.UseBinary = true;
 86 
 87             //open request and get response stream
 88             using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
 89             {
 90                 using (Stream responseStream = response.GetResponseStream())
 91                 {
 92                     //loop to read & write to file
 93                     responseStream.ReadTimeout = 600000;
 94                     using (FileStream fs = targetFI.OpenWrite())
 95                     {
 96                         try
 97                         {
 98                             byte[] buffer = new byte[2048*1000*2];
 99                             int read = 0;
100                             do
101                             {
102                                 read = responseStream.Read(buffer, 0, buffer.Length);
103                                 fs.Write(buffer, 0, read);
104                                 fs.Flush();
105                             } while (read != 0);
106                             responseStream.Close();
107                             fs.Flush();
108                             fs.Close();
109                         }
110                         catch (Exception)
111                         {
112                             //catch error and delete file only partially downloaded
113                             fs.Close();
114                             //delete target file as it's incomplete
115                             targetFI.Delete();
116                             throw;
117                         }
118                     }
119 
120                     responseStream.Close();
121                 }
122 
123                 response.Close();
124             }
125 
126 
127             return true;
128         }
129 
130         #endregion
131 
132         #region "private supporting fns"
133 
134 
135         //Get the basic FtpWebRequest object with the
136         //common settings and security
137         private FtpWebRequest GetRequest(string URI)
138         {
139             //create request
140             FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
141             //Set the login details
142             result.Credentials = GetCredentials();
143             // support for EnableSSL
144             result.EnableSsl = EnableSsl;
145             result.Timeout = 600000;
146 
147             ServicePoint sp = result.ServicePoint;
148             ServicePointManager.ServerCertificateValidationCallback = 
149                 new RemoteCertificateValidationCallback(ValidateServerCertificate);
150 
151             return result;
152         }
153 
154         /// <summary>
155         /// Ensure chars in path are correctly escaped e.g. #
156         /// </summary>
157         /// <param name="path">path to escape</param>
158         /// <returns></returns>
159         private string GetEscapedPath(string path)
160         {
161             string[] parts;
162             parts = path.Split('/');
163             string result;
164             result = "";
165             foreach (string part in parts)
166             {
167                 if (!string.IsNullOrEmpty(part))
168                     result += @"/" + Uri.EscapeDataString(part);
169             }
170             return result;
171         }
172 
173 
174         /// <summary>
175         /// Get the credentials from username/password
176         /// </summary>
177         /// <remarks>
178         /// Amended to store credentials on first use, for re-use
179         /// when using KeepAlive=true
180         /// </remarks>
181         private System.Net.ICredentials GetCredentials()
182         {
183             if (_credentials == null)
184                 _credentials = new System.Net.NetworkCredential(Username, Password);
185             return _credentials;
186         }
187 
188         /// <summary>
189         /// stored credentials
190         /// </summary>
191         private System.Net.NetworkCredential _credentials = null;
192 
193 
194 
195         /// <summary>
196         /// Obtains a response stream as a string
197         /// </summary>
198         /// <param name="ftp">current FTP request</param>
199         /// <returns>String containing response</returns>
200         /// <remarks>
201         /// FTP servers typically return strings with CR and
202         /// not CRLF. Use respons.Replace(vbCR, vbCRLF) to convert
203         /// to an MSDOS string
204         /// 1.1: modified to ensure accepts UTF8 encoding
205         /// </remarks>
206         private string GetStringResponse(FtpWebRequest ftp)
207         {
208             //Get the result, streaming to a string
209             string result = "";
210             using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
211             {
212                 long size = response.ContentLength;
213                 using (Stream datastream = response.GetResponseStream())
214                 {
215                     using (StreamReader sr = new StreamReader(datastream, System.Text.Encoding.UTF8))
216                     {
217                         result = sr.ReadToEnd();
218                         sr.Close();
219                     }
220 
221                     datastream.Close();
222                 }
223 
224                 response.Close();
225             }
226 
227             return result;
228         }
229 
230         /// <summary>
231         /// Gets the size of an FTP request
232         /// </summary>
233         /// <param name="ftp"></param>
234         /// <returns></returns>
235         /// <remarks></remarks>
236         private long GetSize(FtpWebRequest ftp)
237         {
238             long size;
239             using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
240             {
241                 size = response.ContentLength;
242                 response.Close();
243             }
244 
245             return size;
246         }
247 
248         private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
249         {
250             return true;
251         }
252 
253 
254 
255         #endregion
256 
257         #region Properties
258 
259         public string Hostname { get; set; }
260         public string Username { get; set; }
261         public string Password { get; set; }
262         public bool EnableSsl { get; set; }
263 
264         #endregion
265 
266     }
267     #endregion
268 
269 
270 }
FTPClient.cs
 1 using System;
 2 using System.Configuration;
 3 using System.Linq;
 4 
 5 namespace FtpClientBlogCase
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             DownloadFileFromFTP.DownloadFileFromNetwork();
12             Console.WriteLine("Done");
13         }
14     }
15 
16     public class DownloadFileFromFTP
17     {
18         public static void DownloadFileFromNetwork()
19         {
20             var fullDataServer = "XXX";
21             var userName = "XXX";
22             var password = "XXX";
23             var fc = new FTPclient(fullDataServer, userName, password, true);
24             var list = fc.ListDirectory(fullDataServer);
25             Console.WriteLine("The file is downloading, please wait...");
26             fc.Download(fullDataServer + list.Last(), list.Last(), true);
27 
28         }
29     }
30 }
Program.cs

在类FTPClient中,private FtpWebRequest GetRequest(string URI) 是最重要的方法,它为每一个功能提供了一个FtpWebRequest对象,避免了每次生成request对象的冗余冗余代码。

 

转载于:https://www.cnblogs.com/Jason-blogs/p/4558909.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值