項目中常常涉及到將文件批量上傳到其它空間或服務器,這個時候咱們有可能須要用到FTP協議進行傳輸,因此這裏我推薦使用FluentFTP,一款很好用的FTP傳輸框架。git
github地址:https://github.com/robinrodricks/FluentFTPgithub
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:async
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 ONgoogle
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");
第三步,上傳文件:spa
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.Name}", createRemoteDir: true); 12 }
若是想批量上傳文件,則使用ftpClient.UploadDirectoryAsync(),能夠直接上傳整個文件夾。.net
這裏有個比較坑的地方是,若是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除了上述的坑之外,功能仍是很是齊全、強大的,提供了各類各樣的方法和配置,建議你們使用。