FTP/FTPS上传下载支持断点续传

  1     /// <summary>  
  2     /// ftp方式文件下载上传  
  3     /// </summary>  
  4     public static class FileUpDownload
  5     {
  6         #region 变量属性  
  7         /// <summary>  
  8         /// Ftp服务器ip  
  9         /// </summary>  
 10         public static string FtpServerIP = string.Empty;
 11         /// <summary>  
 12         /// Ftp 指定用户名  
 13         /// </summary>  
 14         public static string FtpUserID = string.Empty;
 15         /// <summary>  
 16         /// Ftp 指定用户密码  
 17         /// </summary>  
 18         public static string FtpPassword = string.Empty;
 19 
 20         //public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
 21         #endregion
 22 
 23         #region 从FTP服务器下载文件,指定本地路径和本地文件名  
 24         /// <summary>  
 25         /// 从FTP服务器下载文件,指定本地路径和本地文件名  
 26         /// </summary>  
 27         /// <param name="remoteFileName">远程文件名</param>  
 28         /// <param name="localFileName">保存本地的文件名(包含路径)</param>  
 29         /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>  
 30         /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
 31         /// <returns>是否下载成功</returns>  
 32         public static bool FtpDownload(string remoteFileName, string localFileName, bool ifCredential, Action<int, int> updateProgress = null)
 33         {
 34             FtpWebRequest reqFTP, ftpsize;
 35             Stream ftpStream = null;
 36             FtpWebResponse response = null;
 37             FileStream outputStream = null;
 38             try
 39             {
 40                 outputStream = new FileStream(localFileName, FileMode.Create);
 41                 if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
 42                 {
 43                     throw new Exception("ftp下载目标服务器地址未设置!");
 44                 }
 45                 Uri uri = new Uri("ftp://" + FtpServerIP + "/" + remoteFileName);
 46                 ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
 47                 ftpsize.UseBinary = true;
 48 
 49                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
 50                 reqFTP.UseBinary = true;
 51                 reqFTP.KeepAlive = false;
 52                 if (ifCredential)//使用用户身份认证  
 53                 {
 54                     ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
 55                     reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
 56                 }
 57 
 58                 //SSL
 59                 reqFTP.EnableSsl = true;
 60                 ftpsize.EnableSsl = true;
 61                 //证书回调方法         
 62                 ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
 63 
 64                 //证书
 65                 // X509Certificate cert = X509Certificate.CreateFromCertFile(Application.StartupPath + "/MyCertDir/certificate1.cer");
 66                 //X509Certificate cert = X509Certificate.CreateFromCertFile(@"C:\MyCertDir\MyCertFile1.cer");
 67                 //X509CertificateCollection certCollection = new X509CertificateCollection();
 68                 // certCollection.Add(cert);
 69                 // reqFTP.ClientCertificates = certCollection;
 70 
 71                 ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
 72                 FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
 73                 long totalBytes = re.ContentLength;
 74                 re.Close();
 75 
 76                 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
 77                 response = (FtpWebResponse)reqFTP.GetResponse();
 78                 ftpStream = response.GetResponseStream();
 79 
 80                 //更新进度    
 81 
 82                 //updateProgress(0, 0);
 83                 if (updateProgress != null)
 84                 {
 85                     updateProgress((int)totalBytes, 0);//更新进度条     
 86                 }
 87                 long totalDownloadedByte = 0;
 88                 int bufferSize = 2048;
 89                 int readCount;
 90                 byte[] buffer = new byte[bufferSize];
 91                 readCount = ftpStream.Read(buffer, 0, bufferSize);
 92                 while (readCount > 0)
 93                 {
 94                     totalDownloadedByte = readCount + totalDownloadedByte;
 95                     outputStream.Write(buffer, 0, readCount);
 96                     //更新进度    
 97                     if (updateProgress != null)
 98                     {
 99                         updateProgress((int)totalBytes, (int)totalDownloadedByte);//更新进度条
100                     }
101                     readCount = ftpStream.Read(buffer, 0, bufferSize);
102                 }
103                 ftpStream.Close();
104                 outputStream.Close();
105                 response.Close();
106                 return true;
107 
108             }
109             catch (Exception ex)
110             {
111                 return false;
112                 throw;
113             }
114             finally
115             {
116                 if (ftpStream != null)
117                 {
118                     ftpStream.Close();
119                 }
120                 if (outputStream != null)
121                 {
122                     outputStream.Close();
123                 }
124                 if (response != null)
125                 {
126                     response.Close();
127                 }
128             }
129         }
130 
131         public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
132         {
133             bool allowCertificate = true;
134 
135             if (sslPolicyErrors != SslPolicyErrors.None)
136             {
137                 Console.WriteLine("接受的证书错误:");
138                 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
139                 {
140                     Console.WriteLine("\t证书 {0} 不匹配.", certificate.Subject);
141                 }
142 
143                 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
144                 {
145                     Console.WriteLine("\t证书以下错误信息:");
146                     foreach (X509ChainStatus chainStatus in chain.ChainStatus)
147                     {
148                         Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);
149 
150                         if (chainStatus.Status == X509ChainStatusFlags.Revoked)
151                         {
152                             allowCertificate = false;
153                         }
154                     }
155                 }
156 
157                 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
158                 {
159                     Console.WriteLine("没有可用的证书。");
160                     allowCertificate = false;
161                 }
162 
163                 Console.WriteLine();
164             }
165 
166             return allowCertificate;
167         }
168 
169         /// <summary>  
170         /// 从FTP服务器下载文件,指定本地路径和本地文件名(支持断点下载)  
171         /// </summary>  
172         /// <param name="remoteFileName">远程文件名</param>  
173         /// <param name="localFileName">保存本地的文件名(包含路径)</param>  
174         /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>  
175         /// <param name="size">已下载文件流大小</param>  
176         /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
177         /// <returns>是否下载成功</returns>  
178         public static bool FtpBrokenDownload(string remoteFileName, string localFileName, bool ifCredential, long size, Action<int, int> updateProgress = null)
179         {
180             FtpWebRequest reqFTP, ftpsize;
181             Stream ftpStream = null;
182             FtpWebResponse response = null;
183             FileStream outputStream = null;
184 
185             try
186             {
187                 outputStream = new FileStream(localFileName, FileMode.Append);
188                 if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
189                 {
190                     throw new Exception("ftp下载目标服务器地址未设置!");
191                 }
192                 Uri uri = new Uri("ftp://" + FtpServerIP + "/" + remoteFileName);
193                 ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
194                 ftpsize.UseBinary = true;
195                 ftpsize.ContentOffset = size;
196 
197                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
198                 reqFTP.UseBinary = true;
199                 reqFTP.KeepAlive = false;
200                 reqFTP.ContentOffset = size;
201                 if (ifCredential)//使用用户身份认证  
202                 {
203                     ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
204                     reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
205                 }
206                 //SSL
207                 reqFTP.EnableSsl = true;
208                 ftpsize.EnableSsl = true;
209                 //证书回调方法         
210                 ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
211 
212                 ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
213                 FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
214                 long totalBytes = re.ContentLength;
215                 re.Close();
216 
217                 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
218                 response = (FtpWebResponse)reqFTP.GetResponse();
219                 ftpStream = response.GetResponseStream();
220 
221                 //更新进度    
222                 if (updateProgress != null)
223                 {
224                     updateProgress((int)totalBytes, 0);//更新进度条     
225                 }
226                 long totalDownloadedByte = 0;
227                 int bufferSize = 2048;
228                 int readCount;
229                 byte[] buffer = new byte[bufferSize];
230                 readCount = ftpStream.Read(buffer, 0, bufferSize);
231                 while (readCount > 0)
232                 {
233                     totalDownloadedByte = readCount + totalDownloadedByte;
234                     outputStream.Write(buffer, 0, readCount);
235                     //更新进度    
236                     if (updateProgress != null)
237                     {
238                         updateProgress((int)totalBytes, (int)totalDownloadedByte);//更新进度条     
239                     }
240                     readCount = ftpStream.Read(buffer, 0, bufferSize);
241                 }
242                 ftpStream.Close();
243                 outputStream.Close();
244                 response.Close();
245                 return true;
246             }
247             catch (Exception ex)
248             {
249                 return false;
250                 throw;
251             }
252             finally
253             {
254                 if (ftpStream != null)
255                 {
256                     ftpStream.Close();
257                 }
258                 if (outputStream != null)
259                 {
260                     outputStream.Close();
261                 }
262                 if (response != null)
263                 {
264                     response.Close();
265                 }
266             }
267 
268         }
269 
270         /// <summary>  
271         /// 从FTP服务器下载文件,指定本地路径和本地文件名  
272         /// </summary>  
273         /// <param name="remoteFileName">远程文件名</param>  
274         /// <param name="localFileName">保存本地的文件名(包含路径)</param>  
275         /// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>  
276         /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
277         /// <param name="brokenOpen">是否断点下载:true 会在localFileName 找是否存在已经下载的文件,并计算文件流大小</param>  
278         /// <returns>是否下载成功</returns>  
279         public static bool FtpDownload(string remoteFileName, string localFileName, bool ifCredential, bool brokenOpen, Action<int, int> updateProgress = null)
280         {
281             if (brokenOpen)
282             {
283                 try
284                 {
285                     long size = 0;
286                     if (File.Exists(localFileName))
287                     {
288                         using (FileStream outputStream = new FileStream(localFileName, FileMode.Open))
289                         {
290                             size = outputStream.Length;
291                         }
292                     }
293                     return FtpBrokenDownload(remoteFileName, localFileName, ifCredential, size, updateProgress);
294                 }
295                 catch
296                 {
297                     throw;
298                 }
299             }
300             else
301             {
302                 return FtpDownload(remoteFileName, localFileName, ifCredential, updateProgress);
303             }
304         }
305 
306         #endregion
307 
308         #region 上传文件到FTP服务器
309         /// <summary>  
310         /// 上传文件到FTP服务器  
311         /// </summary>  
312         /// <param name="localFullPath">本地带有完整路径的文件名</param>  
313         /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
314         /// <returns>是否下载成功</returns>  
315         public static bool FtpUploadFile(string localFullPathName, Action<int, int> updateProgress = null)
316         {
317             FtpWebRequest reqFTP;
318             Stream stream = null;
319             FtpWebResponse response = null;
320             FileStream fs = null;
321 
322             try
323             {
324                 FileInfo finfo = new FileInfo(localFullPathName);
325                 if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
326                 {
327                     throw new Exception("ftp上传目标服务器地址未设置!");
328                 }
329                 Uri uri = new Uri("ftp://" + FtpServerIP + "/" + finfo.Name);
330                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
331                 reqFTP.KeepAlive = false;
332                 reqFTP.UseBinary = true;
333                 reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);//用户,密码  
334                 reqFTP.Method = WebRequestMethods.Ftp.UploadFile;//向服务器发出下载请求命令  
335                 reqFTP.ContentLength = finfo.Length;//为request指定上传文件的大小  
336 
337                 reqFTP.EnableSsl = true;
338                 //证书回调方法         
339                 ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
340 
341                 response = reqFTP.GetResponse() as FtpWebResponse;
342                 reqFTP.ContentLength = finfo.Length;
343                 int buffLength = 1024;
344                 byte[] buff = new byte[buffLength];
345                 int contentLen;
346                 fs = finfo.OpenRead();
347                 stream = reqFTP.GetRequestStream();
348                 contentLen = fs.Read(buff, 0, buffLength);
349                 int allbye = (int)finfo.Length;
350                 //更新进度    
351                 if (updateProgress != null)
352                 {
353                     updateProgress((int)allbye, 0);//更新进度条     
354                 }
355                 int startbye = 0;
356                 while (contentLen != 0)
357                 {
358                     startbye = contentLen + startbye;
359                     stream.Write(buff, 0, contentLen);
360                     //更新进度    
361                     if (updateProgress != null)
362                     {
363                         updateProgress((int)allbye, (int)startbye);//更新进度条     
364                     }
365                     contentLen = fs.Read(buff, 0, buffLength);
366                 }
367                 stream.Close();
368                 fs.Close();
369                 response.Close();
370                 return true;
371 
372             }
373             catch (Exception ex)
374             {
375                 return false;
376                 throw;
377             }
378             finally
379             {
380                 if (fs != null)
381                 {
382                     fs.Close();
383                 }
384                 if (stream != null)
385                 {
386                     stream.Close();
387                 }
388                 if (response != null)
389                 {
390                     response.Close();
391                 }
392             }
393         }
394 
395         /// <summary>  
396         /// 上传文件到FTP服务器(断点续传)  
397         /// </summary>  
398         /// <param name="localFullPath">本地文件全路径名称:C:\Users\JianKunKing\Desktop\IronPython脚本测试工具</param>  
399         /// <param name="remoteFilepath">远程文件所在文件夹路径</param>  
400         /// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>  
401         /// <returns></returns>         
402         public static bool FtpUploadBroken(string localFullPath, string remoteFilepath, Action<int, int> updateProgress = null)
403         {
404             if (remoteFilepath == null)
405             {
406                 remoteFilepath = "";
407             }
408             string newFileName = string.Empty;
409             bool success = true;
410             FileInfo fileInf = new FileInfo(localFullPath);
411             long allbye = (long)fileInf.Length;
412             if (fileInf.Name.IndexOf("#") == -1)
413             {
414                 newFileName = RemoveSpaces(fileInf.Name);
415             }
416             else
417             {
418                 newFileName = fileInf.Name.Replace("#", "");
419                 newFileName = RemoveSpaces(newFileName);
420             }
421             long startfilesize = GetFileSize(newFileName, remoteFilepath);
422             if (startfilesize >= allbye)
423             {
424                 return false;
425             }
426             long startbye = startfilesize;
427             //更新进度    
428             if (updateProgress != null)
429             {
430                 updateProgress((int)allbye, (int)startfilesize);//更新进度条     
431             }
432 
433             string uri;
434             if (remoteFilepath.Length == 0)
435             {
436                 uri = "ftp://" + FtpServerIP + "/" + newFileName;
437             }
438             else
439             {
440                 uri = "ftp://" + FtpServerIP + "/" + remoteFilepath + "/" + newFileName;
441             }
442             FtpWebRequest reqFTP;
443             // 根据uri创建FtpWebRequest对象   
444             reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
445             // ftp用户名和密码   
446             reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
447             // 默认为true,连接不会被关闭   
448             // 在一个命令之后被执行   
449             reqFTP.KeepAlive = false;
450             // 指定执行什么命令   
451             reqFTP.Method = WebRequestMethods.Ftp.AppendFile;
452             // 指定数据传输类型   
453             reqFTP.UseBinary = true;
454             // 上传文件时通知服务器文件的大小   
455             reqFTP.ContentLength = fileInf.Length;
456             int buffLength = 2048;// 缓冲大小设置为2kb   
457             byte[] buff = new byte[buffLength];
458             // 打开一个文件流 (System.IO.FileStream) 去读上传的文件   
459             FileStream fs = fileInf.OpenRead();
460             Stream strm = null;
461             try
462             {
463                 // 把上传的文件写入流   
464                 strm = reqFTP.GetRequestStream();
465                 // 每次读文件流的2kb     
466                 fs.Seek(startfilesize, 0);
467                 int contentLen = fs.Read(buff, 0, buffLength);
468                 // 流内容没有结束   
469                 while (contentLen != 0)
470                 {
471                     // 把内容从file stream 写入 upload stream   
472                     strm.Write(buff, 0, contentLen);
473                     contentLen = fs.Read(buff, 0, buffLength);
474                     startbye += contentLen;
475                     //更新进度    
476                     if (updateProgress != null)
477                     {
478                         updateProgress((int)allbye, (int)startbye);//更新进度条     
479                     }
480                 }
481                 // 关闭两个流   
482                 strm.Close();
483                 fs.Close();
484             }
485             catch
486             {
487                 success = false;
488                 throw;
489             }
490             finally
491             {
492                 if (fs != null)
493                 {
494                     fs.Close();
495                 }
496                 if (strm != null)
497                 {
498                     strm.Close();
499                 }
500             }
501             return success;
502         }
503 
504         /// <summary>  
505         /// 去除空格  
506         /// </summary>  
507         /// <param name="str"></param>  
508         /// <returns></returns>  
509         private static string RemoveSpaces(string str)
510         {
511             string a = "";
512             CharEnumerator CEnumerator = str.GetEnumerator();
513             while (CEnumerator.MoveNext())
514             {
515                 byte[] array = new byte[1];
516                 array = System.Text.Encoding.ASCII.GetBytes(CEnumerator.Current.ToString());
517                 int asciicode = (short)(array[0]);
518                 if (asciicode != 32)
519                 {
520                     a += CEnumerator.Current.ToString();
521                 }
522             }
523             string sdate = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString() + System.DateTime.Now.Hour.ToString()
524                 + System.DateTime.Now.Minute.ToString() + System.DateTime.Now.Second.ToString() + System.DateTime.Now.Millisecond.ToString();
525             return a.Split('.')[a.Split('.').Length - 2] + "." + a.Split('.')[a.Split('.').Length - 1];
526         }
527 
528         /// <summary>  
529         /// 获取已上传文件大小  
530         /// </summary>  
531         /// <param name="filename">文件名称</param>  
532         /// <param name="path">服务器文件路径</param>  
533         /// <returns></returns>  
534         public static long GetFileSize(string filename, string remoteFilepath)
535         {
536             long filesize = 0;
537             try
538             {
539                 FtpWebRequest reqFTP;
540                 FileInfo fi = new FileInfo(filename);
541                 string uri;
542                 if (remoteFilepath.Length == 0)
543                 {
544                     uri = "ftp://" + FtpServerIP + "/" + fi.Name;
545                 }
546                 else
547                 {
548                     uri = "ftp://" + FtpServerIP + "/" + remoteFilepath + "/" + fi.Name;
549                 }
550                 reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
551                 reqFTP.KeepAlive = false;
552                 reqFTP.UseBinary = true;
553                 reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);//用户,密码  
554                 reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
555                 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
556                 filesize = response.ContentLength;
557                 return filesize;
558             }
559             catch
560             {
561                 return 0;
562             }
563         }
564 
565 
566         #endregion

 

转载于:https://www.cnblogs.com/OLDMAN-LU/p/6478652.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值