1. 程式人生 > 實用技巧 >.NET Core下好用的FTP框架 FluentFTP

.NET Core下好用的FTP框架 FluentFTP

  專案中經常涉及到將檔案批量上傳到其它空間或伺服器,這個時候我們有可能需要用到FTP協議進行傳輸,所以這裡我推薦使用FluentFTP,一款很好用的FTP傳輸框架。

  github地址:https://github.com/robinrodricks/FluentFTP

  Nuget安裝一下:

PM> Install-Package FluentFTP

  首先new一個Client:

 1 /*
 2 第一個引數是FTP地址,注意要加協議名
 3 第二個引數是埠,預設21
 4 第三個引數是FTP使用者名稱
 5 第四個引數是FTP密碼
 6 正常情況下配置三個屬性即可,大家按需選擇:
7 EncryptionMode是指定加密方式,這裡我選擇None不加密, 8 DataConnectionType是連線方式,一般都是選PASV被動模式或PORT主動模式,根據FTPServer情況修改 9 Encoding是指定編碼 10 */ 11 var ftpClient = new FtpClient($"ftp://{host}", port, userName, passWord) 12 { 13 EncryptionMode = FtpEncryptionMode.None, 14 DataConnectionType = FtpDataConnectionType.PASV,
15 Encoding = Encoding.UTF8 16 };

  接下來第一步,登入FTP:

 1 //IsConnected是判斷client是否與遠端服務建立了連線
 2 if (!ftpClient.IsConnected)
 3 {
 4     //發起連線登入
 5     await ftpClient.ConnectAsync();
 6     //啟用UTF8傳輸
 7     var result = ftpClient.Execute("OPTS UTF8 ON");
 8     if (!result.Code.Equals("200") && !result.Code.Equals("
202")) 9 ftpClient.Encoding = Encoding.GetEncoding("ISO-8859-1"); 10 }

  這裡有一個比較坑的地方,不瞭解FTP的夥伴有可能會糾結半天,那就是檔案如果是中文檔名,上傳後文件名會變成亂碼。原因是因為有一些FTPServer預設是不開啟UTF8編碼傳輸,甚至不支援UTF8編碼傳輸,這個時候需要我們手動開啟一下,FTP命令是OPTS UTF8 ON

ftpClient.Execute("OPTS UTF8 ON");

  這個時候會伺服器會返回一個狀態碼,200表示開啟成功;202是always enable,表示FTPServer會一直處於開啟狀態,不需要手動開啟。

  但除此之外,還有剛才提到的,FTPServer本身不支援這種UTF8編碼的傳輸,這個時候我們需要將之前的Encoding設定為ISO-8859-1。

ftpClient.Encoding = Encoding.GetEncoding("ISO-8859-1");

  第二步,上傳檔案:

 1 /// <summary>
 2 /// 上傳單個檔案
 3 /// </summary>
 4 /// <param name="sourcePath">檔案源路徑</param>
 5 /// <param name="destPath">上傳到指定的ftp資料夾路徑</param>
 6 public async void UploadFile(string sourcePath, string destPath)
 7 {
 8      if (!File.Exists(sourcePath))
 9          return;
10      var fileInfo = new FileInfo(sourcePath);
11      await ftpClient.UploadFileAsync(sourcePath, destPath, createRemoteDir: true);
12 }

  如果想批量上傳,則使用ftpClient.UploadDirectoryAsync(),可以直接上傳整個資料夾;這裡有個比較坑的地方是,如果FTPServer目錄下的檔案特別多(不是指你上傳檔案的數量),上傳所需的時間會特別長。在我查看了FTP日誌後發現,在使用UploadDirectoryAsync()的時候,FluentFTP會先去獲取所有檔案和資料夾的列表,在嘗試解決無果後,我去github上找了一下,作者的回覆是:

  Currently we support 2 modes, update and mirror. In any mode, the remote directory is fully listed, then compared, then the actually upload begins. This is done in order to skip files that are already uploaded. We can support a third mode, maybe like BlindTransfer which will not list the remote directory.

  google翻譯:目前,我們支援2種模式:更新和映象。 在任何模式下,遠端目錄都會完整列出,然後進行比較,然後開始實際的上載。 這樣做是為了跳過已經上傳的檔案。 我們可以支援第三種模式,例如BlindTransfer,它不會列出遠端目錄。

  但在目前最新版本33.0.3版本下,仍舊只支援Mirror和Update。

  Issues:https://github.com/robinrodricks/FluentFTP/issues/616

  所以,如果需要批量上傳,可以在單檔案上傳的基礎上自己再做一層封裝,至於其它的下載、刪除、檢視等功能,暫未發現其它的坑,環境.net core 3.1。

  這裡只舉幾個常用的方法,其餘的不過多贅述,大家看文件和框架的註釋就行:

//下載檔案
ftpClient.DownloadFileAsync();
//下載資料夾
ftpClient.DownloadDirectoryAsync();
//刪除檔案
ftpClient.DeleteFileAsync();
//刪除資料夾
ftpClient.DeleteDirectoryAsync();
//判斷檔案是否存在
ftpClient.FileExistsAsync();
//判斷資料夾是否存在
ftpClient.DirectoryExistsAsync();
//獲取列表的詳細資訊
ftpClient.GetListingAsync();

  最後,記住登出、釋放資源:

1 if (ftpClient.IsConnected)
2 {
3     //關閉
4     await ftpClient.DisconnectAsync();
5     ftpClient.Dispose();
6 }