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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM