專案中經常涉及到將檔案批量上傳到其它空間或服務器,這個時候我們有可能需要用到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");
這個時候FTPServer會回傳一個狀態碼,200表示開啟成功;202是always enable,表示FTPServer會一直處于開啟UTF-8編碼的狀態,不需要手動開啟,
但除此之外,還有剛才提到的,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}/{fileInfo.FileName}", createRemoteDir: true); 12 }
如果想批量上傳檔案,則使用ftpClient.UploadDirectoryAsync(),可以直接上傳整個檔案夾,
這里有個比較坑的地方是,如果FTPServer目錄下的檔案特別多(注意:不是你上傳檔案的數量),上傳所需的時間會特別長,在我查看了FTPServer日志后發現,在使用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 }
FluentFTP除了上述的坑以外,功能還是非常齊全、強大的,提供了各種各樣的方法和配置,建議大家使用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/239362.html
標籤:.NET技术
上一篇:WPF影像裁剪控制元件
下一篇:[WPF] 在 ViewModel 中讓資料驗證出錯(Validation.HasError)的控制元件獲得焦點
