FluentFTP中文翻譯
翻譯時間:2020/1/28
謝謝支持與關注!~
請勿轉載或者以任何形式的進行抄寫!~
本文由博主自譯,其中有部分內容屬於博主個人理解,如果有錯誤請多多包涵!
原文的地址:https://github.com/robinrodricks/FluentFTP
翻譯 by戀如雨止
博客園:https://www.cnblogs.com/Jeffrey-Chou/
如果想要Word版本的翻譯文檔請評論留下QQ注明要翻譯文檔,看到我都會給的!~
前言
FluentFTP是提供給.NET和.NET Standard使用的,一個完全由托管的FTP和FTPS實現的經過速度優化的類庫。它提供了全面的FTP的指令,功能包括文件上傳/下載,SSL/TLS連接,自動目錄清單列表解析,文件哈希/校驗和,文件權限/CHMOD權限,FTP代理,UTF-8編碼支持,Async/await支持,Powershell支持等等。
FluentFTP完全是由C#語言編寫的,並且沒有額外的依賴。它是在寬松的MIT許可下發布的,因此,FluentFTP既可以用於私有的應用程序,也可以用於自由/開源的應用程序。
如果你需要讓一個特定的問題優先進行支持,可以考慮使用IssueHunt為處理這個問題提供資金資助。
特性
- 全面支撐FTP、FTPS(SSL下的FTP)、客戶端證書FTP和CCC(用於FTP防火牆)的FTPS
- 文件管理:
- 為主要的服務器類型(例如Unix、Windows/IIS、Azure、Pure-FTPd、ProFTPD、Vax、VMS、OpenVMS、Tandem、HP NonStop Guardian、IBM OS/400、AS400、Windows CE、Serv-U)提供文件和文件夾清單列表顯示
- 完全遞歸的目錄清單列表和目錄刪除(手動遞歸和服務器遞歸)
- 帶有進度跟蹤方式,輕松地從服務器上上傳和下載一個文件
- 自動驗證文件的哈希值,並且在文件哈希值不匹配的時候重新嘗試傳輸
- 多文件傳輸的可配置錯誤處理(忽略/終止/拋出)
- 使用標准的流,輕松地從服務器讀取和寫入文件數據
- 創建、附加、讀取、寫入、重命名、移動刪除文件和文件夾
- 遞歸刪除文件夾及其所有內容
- 獲取文件/文件夾信息(存在、大小、安全標志、修改日期/時間)
- 獲取和設置文件的權限(所有者、組、其他)
- 絕對路徑或相對路徑(相對於“工作目錄”)
- 獲取文件的哈希值和校驗和(SHA-1、SHA-256、SHA-512和MD5)
- 取消對符號鏈接的引用,以計算鏈接的文件/文件夾
- 通過可配置的速度限制,節流上傳和下載
- FTP協議:
- 自動檢測工作連接設置和自動連接協定
- 自動檢測FTP服務器軟件以及它的性能
- 對FTP命令的廣泛的支持,包括一些特定於服務器的命令
- 使用Execute()方法可以輕松地發送服務器特定的FTP命令
- 使用.NET的SslStream,顯式或者隱式對控制和數據提供SSL連接的支持
- 無源和有源的數據連接(PASV、EPSV、PORT和EPRT)
- 支持Unix CHMOD,PRET,ProFTPD的SITE MKDIR和RMDIR命令,Serv-U的RMDA命令
- 支持FTP代理(User@Host,HTTP 1.1,BlueCoat)
- FTP命令日志通過使用TraceListeners(密碼省略)來跟蹤或者記錄輸出到一個文件中
- 不支持SFTP,因為它是通過SSH的FTP,這是一個完全不同的協議(請使用SSH.NET來處理)
- 異步支持:
- 對於所有的方法可以通過使用async/await來實現同步和異步的方法
- 通過使用IAsyncResult方式(Begin*/End*)支持.NET 4.0及其以下的的版本,來實現方法的異步調用
- 所有的異步方法都可以通過傳遞一個CancellationToken來實現中途的取消
- 所有的異步方法都遵循ReadTimeout,並且在超時的時候,它們會自動取消自己
- 通過克隆文件傳輸的FTP控制連接來提高文件線程的安全性(可選)
- 實現自己內部的鎖定,以保持事務的同步
- 可擴展:
- 輕松地添加對更多的代理類型的支持(簡單地繼承FTPClientProxy)
- 輕松地取消對目錄清單列表解析器的支持(參閱例子CustomParser)
- 通過使用FtpTrace.AddListener來實現輕松的添加自定義日志/跟蹤的功能
- 通過擴展FluentFTP.ps1中的腳本,可以輕松的添加自己的Powershell命令
發布
穩定的二進制文件在NuGet上發布,包含在.NET/CLR應用程序中使用FTP/FTPS所需的所有內容。相關的用法,請參閱下面的示例用法的部分和文檔的部分。
- Nuget(最新的)
- Release Notes(每個發布版本的特性和修復)
FluentFTP工作在.NET和.NET Standard/.NET Core。
平台 |
二進制文件夾 |
.NET 2.0 |
net20 |
.NET 3.5 |
net35 |
.NET 4.0 |
net40 |
.NET 4.5 |
net45 |
.NET Standard 1.4 |
netstandard1.4 |
.NET Standard 1.6 |
netstandard1.6 |
.NET Standard 2.0 |
Netstandard2.0 |
這些平台也支持FluentFTP:(通過.NET Standard)
- Mono 4.6
- Xamarin.iOS 10.0
- Xamarin.Android 10.0
- Universal Windows Platform 10.0
所有平台的二進制文件都是由一個VS 2017項目來構建的。您需要使用VS 2017來構建或者修正FluentFTP。
使用例子
//創建一個FTP客戶端 FtpClient client = new FtpClient(“123.123.123.123”); //如果您沒有指定登錄的憑證,我們將使用“匿名”用戶賬戶 client.Credentials = new NetworkCredential(“david”,”pass123”); //開始連接到服務器 client.Connect(); //獲得一個在“/htdocs”目錄下的文件和文件夾的列表 foreach(FtpListItem item in client.GetListing(“/htdocs”)){ //如果這個是一個文件 if(item.Type == FtpFileSystemObjectType.File){ //獲得這個文件的大小 long size = client.GetFileSize(item.FullName); } //獲得文件或者文件夾的修改日期和時間 DateTime time = client.GetModifiedTime(item.FullName); //計算文件在服務器端的哈希值(默認的算法) FtpHash hash = client.GetHash(item.FullName); } //上傳一個文件 client.UploadFile(@”C:\MyVideo.mp4”,”/htdocs/MyVideo.mp4”); //重命名這個上傳的文件 client.Rename(“/htdocs/MyVideo.mp4”,”/htdocs/MyVideo_2.mp4”); //下載這個文件 client.DownloadFile(@”C:\MyVideo_2.mp4”,”/htdocs/MyVideo_2.mp4”); //刪除文件 client.DeleteFile(“/htdocs/MyVideo_2.mp4”); //遞歸地刪除一個文件夾 client.DeleteDirectory(“/htdocs/extras/”); //檢查文件是不是存在 if(client.FileExists(“/htdocs/big2.txt”)){} //檢查一個文件夾是不是存在 if(client.DirectoryExists(“/htdocs/extras/”)){} //上傳一個文件,並且如果失敗,在失敗之前會重新嘗試三次 client.RetryAttempts=3; client.UploadFile(@”C:\MyVideo.mp4”,”/htdocs/big.txt”,FtpExists.Overwrite,false,FtpVerify.Retry); //斷開連接!再見~ client.Disconnect();
Powershell
你可以使用FluentFTP將文件從Powershell腳本傳輸到FTP服務器。開始:
- 在Powershell中,按照它的報告下載所有的文件
- 將內容放入C:\Scripts或您選擇的任何的文件夾中
- 在Powershell中運行這個命令,使FluentFTP函數可用:
>. C:\Scripts\FluentFTP.ps1 #Makes functions callable from PowerShell scripts
- 運行你需要的命令!(下面給出命令示例)
> Show-FtpFile -Site ftp.mysite.com -User bob -Password secure -FtpDirectory pub -FtpFileName "text*" > Rename-File -Site ftp.mysite.com -User bob -Password secure -FtpDirectory pub -oldName "Readme.txt -newName Readme.done" > Send-FtpFile -Site ftp.mysite.com -User bob -Password secure -FtpDirectory pub -fileName "Read*" > Get-FtpFile -Site ftp.mysite.com -User bob -Password secure -FtpDirectory pub -ftpfileName "Read*" > Remove-FtpFile -Site ftp.mysite.com -User bob -Password secure -FtpDirectory pub -ftpfileName "Read*"
在Powershell中運行以下命令可以打印出每個命令的幫助:
> get-help -full Show-FtpFile > get-help -full Rename-FtpFile > get-help -full Send-FtpFile > get-help -full Get-FtpFile > get-help -full Remove-FtpFile
文檔
- API 文檔
- 連接(Connection)
- 服務器(Server)
- 文件夾清單列表(Directory Listing)
- 文件傳輸(File Transfer)
- 文件管理(File Management)
- 文件權限(FIle Permissions)
- 文件哈希(File Hashing)
- 工具(Utilities)
- 日志(Logging)
- 設置
- FTP設置(FTP Settings)
- 顯式的FTP設置(Active FTP Settings)
- FTPS設置(FTPS Setting)
- 文件列表化設置(File Listing Settings)
- 文件傳輸設置(File Transfer Settings)
- 超時設置(Timeout Settings)
- Socket連接設置(Socket Settings)
- FTP支持表
- 例子
- 發布日志
- 相關注釋
常見問題
注:檢查這些常見問題和已經解決的常見問題。
日志相關的常見問題
- 如何在調試時追蹤FTP命令?
- 如何在調試記錄所有的FTP命令?
- 如何將關鍵錯誤記錄到文件中?
- 如何禁用函數調用的日志記錄?
- 如何中日志中省略掉敏感的信息?
- 如何使用像NLog這樣的第三方日志記錄框架?
連接相關的常見問題
- 如何自動檢測正確的連接設置?
- 如何自動連接到FTP或FTPS服務器?
- 如何連接SSL/TLS?如何使用FTPS?
- 如何在使用FTPS時驗證服務器的證書?
- 如何使用SSL/TLS連接到Azure?
- 如何連接FTPS,然后切換回純文本(Plaintext)的FTP?
- 如何連接SFTP?
- 如何中使用匿名的FTP賬戶登錄?
- 如何使用FTP代理登錄?
- 如何檢測正在連接的服務器的類型?
- 如何使用客戶端證書登入FTPS?
- 如何從一個文件捆綁X509證書?
文件傳輸的常見問題
- 如何追蹤文件的傳輸進度?
- 如何上傳動態創建的數據?
- 如何下載數據而不將其保存到磁盤?
- 如何繼續下載一個文件?
- 如何繼續上傳一個文件?
- 如何控制上傳和下載的速度?
- 如何驗證文件的哈希值/校驗和,如果校驗和不匹配,如何重試?
- 如何追加到一個文件?
- 如何使用低級的(low-level)API下載文件?
- 如果我的服務器不支持UTF-8,如何上傳/下載Unicode文件名的文件?
文件管理的常見問題
- GetListing()如何在內部工作?
- GetListing()如何返回一個遞歸的文件列表?
- 支持哪種散列命令?
Misc的常見問題
- EnableThreadSafeDataConnections做什么?
- 如何對FluentFTP做一些修改?
- 如何提交一個拉取請求(a pull reqest)?
一些非常常見的問題
- 無法從傳輸連接讀取數據:遠程主機強制關閉了現有連接
- 嘗試從套接字流(the socket stream)讀取數據時超時
- FTPS不能在Linux上工作,因為它不支持SSL會話恢復
常見問題
- 我在登陸時發生錯誤,但是我可以在Firefox/Filezilla中正常登陸
- 在Visual Studio 2010中Fluent安裝失敗:“System.Runtime”已經為“FluentFTP”定義了一個依賴項
- 上傳一個帶有特殊字符的文件,像是“Caffè.png”,在FTP服務器上,它表現為“Caff?.png”。這個服務器只支持ASCII,但是這個“è”是ASCII。FileZilla可以上傳這個文件,並且沒有任何問題
- 如何文件名中含有俄文字母,我無法刪除這個文件。但是FileZilla可以刪除這個文件,並且沒有問題
- 我總是在我的Azure WebApp中發生TimeoutException異常
- 許多的命令無法在Windows CE上正常工作
- 使用OpenWrite/OpenAppend成功傳輸單個文件后,后續文件失敗,出現一些隨機錯誤,如“格式錯誤的PASV響應”
- 在FTPS的登入期間,SSL協商非常緩慢
API
FtpClient類的全部的API文檔都是用來處理所有的FTP/FTPS功能。
注:所有的方法都支持同步和異步的版本。只需在.NET 4.5+的版本中,為Async/await語的添加“Async”后綴,或者在.NET 4.0及以下版本的方法中添加“Begin”/“End”的前綴。
連接
- new FtpClient() - 創建並返回一個新的FTP客戶端實例。
- Host - FTP服務器的IP地址或者是主機名稱。是必須的。
- Port - FTP連接的端口。默認為:自動(依據FTPS的配置config為21或者是990端口)
- Credentials - FTP的所使用的用戶名稱和密碼。必須是在服務器上注冊的有效的用戶賬戶。默認為:anonymous/anonymous
- Connect() - 連接到FTP服務器(如果配置了的情況下會使用TLS/SSL)。
- Disconnect() - 立即關閉與服務器的FTP連接。
- AutoDetect() - 自動發現FTP連接的設置並且返回這些連接的配置文件。
- AutoConnect() - 自動發現FTP連接的設置並且使用這些配置去連接服務器。
- Excute() - 執行自定義或不支持的命令。
- IsConnected - 檢查連是否仍然是活動的。
- IsClose - 檢查此控制連接是否為克隆。默認為:false
- LastReply - 返回從服務器接收到的最后一個FtpReply。
服務器
- ServerType - 獲得我們所連接的FTP服務器軟件的類型,返回值為FtpServer枚舉類型。請參閱受支持的FTP服務器列表。默認值為:FtpServer.Unknown
- ServerOS - 獲得我們所連接的FTP服務器的操作系統的軟件類型,返回值為FtpOS枚舉類型。請參閱支持的操作系統的類型列表。默認值為:FtpOS.Unknown
- SystemType - 獲取我們所連接的系統/服務器的類型。
- Capabilities - 獲取服務器的性能(由標志位標識)。
- HasFeature() - 檢查服務器是不是支持某個特定的特性(FtpCapability)。
目錄清單
- GetListing() - 獲得一個給定的文件夾的目錄清單。添加FtpListOption.Recursive來遞歸地列出所有子目錄的目錄清單。每一個文件或者文件夾返回一個帶有所有可用屬性集合的FtpListItem。每一個FtpListItem包含:
- Type:對象的類型(文件、目錄或鏈接)。
- Name:對象的名稱(去除路徑)。
- FullName:對象的完整文件路徑。如果文件名看上去是錯誤的,那么請選擇正確的編碼。
- Created:對象的創建日期/時間。如果服務器沒有提供這個值,默認值為:DateTime.MinValue。
- Modified:對象的最近一次的修改日期/時間。如果您獲得了一個不正確的值,那么嘗試添加FtpListOption.Modify標志位來使用另外一種MDTM命令的方式加載對象的修改時間。如果服務器沒有提供這個值,默認值為:DateTime.MinValue
- Size:文件的字節大小。如果您獲得了一個不正確的值,那么嘗試添加FtpListOption.Size標志位來使用另外一種SIZE命令的方式加載文件的大小。如果服務器沒有提供這個值,默認值為:0。
- LinkTarget:連接指向的完整文件路徑。僅為符號連接填充。
- LinkObject:連接指向的文件/文件夾。在FtpListOption.DerefLink標志位被使用的時候,僅用於符號連接填充。
- SpecialPermissions:獲得特殊的權限,比如Stiky、SUID和SGID。
- Chmod:對象的CHMOD權限。例如644或者755。如果服務器沒有提供這個值,默認值為:0。
- OwnerPermissions:用戶的權限。“r”、“w”、“x”的任意組合(使用FtpPermission枚舉)。如果服務器沒有提供這個值,默認值為:FtpPermission.None。
- GroupPermissions:組的權限。“r”、“w”、“x”的任意組合(使用FtpPermission枚舉)。如果服務器沒有提供這個值,默認值為:FtpPermission.None。
- OtherPermissions:其他權限。“r”、“w”、“x”的任意組合(使用FtpPermission枚舉)。如果服務器沒有提供這個值,默認值為:FtpPermission.None。
- RawPermissions:為此對象接收的原始權限字符串。如果其他的權限為空或者無效,請使用此屬性。
- Input:服務器為此對象返回的原始字符串。如果正確解析了上述屬性,則有助於調試。
- GetNameListing() - 使用NLST命令返回給定目錄中的文件路徑列表的簡單命令。
- GetObjectInfo() - 獲取單個文件或者目錄的FtpListItem信息。它包含了類型、創建日期、修改日期、文件大小、權限/chmod和連接目標(如果有的話)。
文件傳輸
高級API:
- Upload() - 上傳一個流或者byte[]到服務器。如果成功的話就返回為true,如果失敗或者文件不存在那么返回為false。對於關鍵的錯誤會拋出異常。支持非常大的文件上傳,因為它的上傳是用數據塊來實現的。
- Download() - 從服務器下載一個文件到流中或者byte[]中。如果成功的話就返回為true,如果失敗或者文件不存在那么返回為false。對於關鍵的錯誤會拋出異常。支持非常大的文件下載,因為它的下載是用數據塊來實現的。
- UploadFile() - 從本地的文件系統上傳一個文件到服務器上。使用FtpExists.Append來恢復繼續一個部分的上傳。如果成功的話就返回為true,如果失敗或者文件不存在那么返回為false。對於關鍵的錯誤會拋出異常。支持非常大的文件上傳,因為它的上傳是用數據塊來實現的。可以可選地驗證一個文件的哈希值,並且在哈希匹配失敗的時候重新嘗試傳輸。
- DownloadFile() - 從服務器上下載一個文件到本地的文件系統。使用FtpExists.Append來恢復繼續一個部分的下載。如果成功的話就返回為true,如果失敗或者文件不存在那么返回為false。對於關鍵的錯誤會拋出異常。支持非常大的文件下載,因為它的下載是用數據塊來實現的。可以可選地驗證一個文件的哈希值,並且在哈希匹配失敗的時候重新嘗試傳輸。
- UploadFiles() - 從本地的文件系統上傳多個文件到服務器上的單個文件夾中。返回上傳的文件的數目。跳過上傳的文件不會被計數。在文件上傳的過程中,用戶可以自定義處理捕獲的異常錯誤(忽略/終止/拋出)。可以可選地驗證一個文件的哈希值,並且在哈希匹配失敗的時候重新嘗試傳輸。比使用UploadFile()上傳多次的速度快。
- DownloadFiles() - 從服務器上下載多個文件到本地文件系統的一個文件夾中。返回下載的文件的數目。跳過下載的文件不會被計數。在文件下載的過程中,用戶可以自定義處理捕獲的異常錯誤(忽略/終止/拋出)。可以可選地驗證一個文件的哈希值,並且在哈希匹配失敗的時候重新嘗試傳輸。
低級API:
- OpenRead() - (最好使用Download()來下載文件為一個Stream或者一個byte[])打開一個流來讀取指定的文件。返回一個標准的stream。在你成功的傳輸文件之后,請調用GetReply()來讀取服務器發送的“OK”指令,並防止套接字上的數據過時。
- OpenWrite() - (最好使用Upload()來上傳一個Stream或者一個byte[])打開一個流來寫入指定的文件。返回一個標准的stream,任何寫入的數據都將覆蓋整個文件,如果文件不存在,那么會被創建。在你成功的傳輸文件之后,請調用GetReply()來讀取服務器發送的“OK”指令,並防止套接字上的數據過時。
- OpenAppend() - (最好使用帶有FtpExists.Append標志的Upload()來上傳一個Stream或者byte[])打開一個流來附加到指定的文件。返回一個標准的stream,任何寫入的數據都將附加到文件數據的尾部。在你成功的傳輸文件之后,請調用GetReply()來讀取服務器發送的“OK”指令,並防止套接字上的數據過時。
文件管理
工作目錄(相對的路徑相對於當前的工作目錄):
- GetWorkingDirectory() - 獲取當前工作目錄的完整路徑。
- SetWorkingDirectory() - 設置當前的工作目錄的完整路徑。所有的相對路徑都相對於當前工作目錄。
目錄:
- DirectoryExists() - 檢查服務器上一個目錄是不是存在。
- CreateDirectory() - 在服務器上創建一個文件目錄。如果不是空的,那么遞歸刪除所有子目錄和文件。
- DeleteDirectory() - 刪除服務器上指定的目錄。如果不是空的,則遞歸刪除所有子目錄和文件。
- MoveDirectory() - 將目錄從服務器上的一個位置移動到另一個位置。如果FtpExists.OverWrite標志被使用的話,則在移動之前刪除目標目錄。只對關鍵錯誤拋出異常。
文件:
- FileExists() - 檢查服務器上是否存在文件。
- DeleteFile() - 刪除服務器上的指定文件。
- MoveFile() - 將文件從服務器上的一個目錄移動到另一個目錄。如果FtpExists.OverWrite標志被使用的話,則在移動之前刪除目標文件。只對關鍵錯誤拋出異常。
- Rename() - 重命名服務器上的文件/文件夾名稱。在大多數情況下不應該使用的低級方法,而是應該使用MoveFile()和MoveDirectory()來重命名文件/文件夾。如果源文件(被重命名)的目標不存在,或者目標(要修改名稱的)已經存在,則拋出異常。
- GetModifiedTime() - 獲取文件或文件夾的最后的修改日期/時間。結果可能在服務器時區、本時或者是UTC,這取決於type參數。
- SetModifiedTime() - 修改文件或文件夾的最后修改日期/時間。根據輸入type參數的不同,輸入可以在服務器時區、本地時區或者UTC中。
- GetFileSize() - 獲取文件的大小(以字節為單位),如果未找到則為-1。
- DereferenceLink() - 遞歸地接觸對一個符號鏈接的引用,並且如果找到,則返回完整路徑。在放棄這個操作之前,我們通過MaximumDereferenceCount屬性來控制遞歸的深度。
文件權限
大多數的服務器支持的標准命令
- GetChmod() - 獲取文件/文件夾的CHMOD權限,如果沒有找到則為0。
- GetFilePermissions() - 以帶有所有“權限”屬性的集合的FtpListItem對象的形式,獲取給定文件/文件夾的權限,如果沒有找到的話,就返回為null。
只支持安裝並啟用了CHMOD擴展的UNIX FTP服務器
- Chmod() - 通過給出CHMOD的值,修改給定的文件/文件夾的權限。
- SetFilePermissions() - 通過給出的分離的擁有者/組/其他的值,修改給定的文件/文件夾的權限(FtpPermission枚舉)。
文件哈希
(筆記:高級的文件傳輸API支持在上傳/下載之后自動進行文件哈希)
大多數的服務器支持的標准命令
- HashAlgorithms - 如果服務器有的話,獲取服務器支持的散列類型(由標志位標識)。
- GetHash() - 使用當前選定的散列算法獲取服務器上對象的散列值。支持的算法可用於HashAlgorithms屬性。您應該確認它不等於FtpHashAlgorithms.NONE(這意味着服務器不支持HASH命令)。
- GetHashAlgorithm() - 為HASH指令查詢服務器當前所選擇的哈希算法。
- SetHashAlgorithm() - 為HASH指令選擇一個哈希算法,並將這個選擇的算法存儲在服務器上。
僅由某些服務器支持的非標准的命令。查看更多
- GetChecksum() - 使用服務器支持的校驗和方法(如果有的話)檢索給定文件的校驗和。所使用的算法以下面的順序:HASH、MD5、XMD5、XSHA1、XSHA256、XSHA512、XCRC。
- GetMD5() - 檢索給定文件的MD5校驗和(如果服務器支持)。
- GetXMD5() - 檢索給定文件的MD5校驗和(如果服務器支持)。
- GetXSHA1() - 檢索給定文件的SHA1校驗和(如果服務器支持)。
- GetXSHA256() - 檢索給定文件的SHA256校驗和(如果服務器支持)。
- GetXSHA521() - 檢索給定文件的SHA512校驗和(如果服務器支持)。
- GetXCRC() - 檢索給定文件的CRC32校驗和(如果服務器支持)。
工具
請導入FluentFTP來使用這些擴展方法,或者直接在FtpExtensions類中訪問它們。
- GetFtpPath(path) - 將指定的本地文件/目錄路徑轉換為有效的FTP文件系統路徑。
- GetFtpPath(path,segments) - 通過將指定的段附加到此字符串來創建有效的FTP路徑。
- GetFtpDirectoryName(path) - 獲取給定文件路徑的父目錄路徑。
- GetFtpFileName(path) - 從路徑獲取文件名和擴展名(如果擴展名存在的話)。
- GetFtpDate(date,styles) - 嘗試將字符串FTP日期表示形式轉換為日期時間對象。
- FileSizeToString(bytes) - 將文件大小(以字節為單位)轉換為字符串表示形式(例如,12345轉換為12.3 KB)。
請直接訪問FtpClient類下的這些靜態方法。
- GetPublicIP() - 使用Ipify服務計算您電腦的公共IP地址。如果你在連接在路由器網絡中或沒有一個靜態的IP地址。
日志
有關日志和調試的幫助,請參閱FAQ的條目。
- client.OnLogEvent - FtpClient的一個屬性。分配給這個屬性一個回調函數,那么這個回調會在每次記錄信息的時候被觸發。
- FtpTrace.LogFunctions - 在記錄日志的時候,是否記錄高級函數的調用。默認值為:true
- FtpTrace.LogIP - 在記錄日志的時候,是否將服務器IP地址進行記錄。默認值為:true
- FtpTrace.LogUserName - 在記錄日志的時候,是否將用戶的名稱進行記錄。默認值為:true
- FtpTrace.LogPassword - 在記錄日志的時候,是否將密碼進行記錄。默認值為:false
- FtpTrace.LogPrefix - 所有的日志信息之前都使用“FluentFTP”前綴。默認值為:false
- FtpTrace.WriteLine - 將消息或錯誤記錄到所有已注冊的偵聽器。
僅.NET Standard可用
- FtpTrace.LogToConsole - 是否應該將FTP通信(communication)記錄到控制台(Console)。默認值為:false
- FtpTrace.LogToFile - 是否設置一個文件的路徑,來將所有的FTP通信(communication)來附加到這個文件中。默認值為:false
僅.NET Framework可用
- FtpFrace.FlushOnWrite - 是否在寫入每個命令后刷新跟蹤偵聽器。默認值為:true
- FtpFrace.AddListener - 向系統中(指的是FluentFTP)添加一個日志處理程序。了解更多
- FtpFrace.RemoveListener - 從系統中移除一個日志處理程序。
設置
FTP設置
可以自動檢測服務器上的FTP連接設置。
- DataConnectionType - 設置連接是活動還是被動的鏈接。默認值為:FtpDataConnectionType.AutoPassive(嘗試EPSV,然后PASV,最后就放棄)
- Encoding - 與服務器進行通信的時候所使用的的文本編碼(ASCII或者UTF8)。ASCII是默認的值,但是在連接的時候,如果服務器支持的話,我們將切換到UTF8編碼。手動設置設置這個值的話講覆蓋自動檢測。默認值為:Auto。
- InternetProtocolVersions - 在進行連接的時候使用IPV4和/還是IPV6。在名稱解析期間返回的所有地址都將被嘗試,直到連接成功為止。默認值為:Any。
- UngracefullDisconnection - 服務器在斷開連接的時候是否發送QUIT。默認值為:false
- SendHost - 在我手之后立刻發送HOST指令。當你使用共享的主機並且你需要通知你想要連接到那個主機的域的情況下,這個是非常有用的。默認值為:false
- SendHostDomain - 控制哪一個域要被發送HOST命令。如果這個值為null,那么FTP客戶端的主機參數將會被發送。默認值為:nulll
主動的FTP設置
- ActivePorts - 設置嘗試給主動的FTP連接所使用的端口,如果為null就會自動選擇一個端口。默認值為:null。
- AddressResolver - 用於解析本地地址的委托,用於活動數據連接。如果你在路由器的網絡下,你可以使用這個,但是端口轉發配置為將端口從路由器轉發到內部IP。在這種情況下,我們需要發送路由器的IP而不是內部IP。
FPTS設置
請在調用Connect()之前設置這些配置。可以自動地檢測這些工作在你服務器上的FTPS連接設置。
- EncrytionMode - 要使用的SSL類型,或者為null。顯式是TLS,隱式是SSL。默認值為:FtpEncryptionMode.None。
- DataConnctionEncryption - 指示是否應加密數據通道傳輸。默認值為:true。
- SslProtocols - 要使用的加密協議。默認值為:SslProtocols.Default。
- SslBuffering - 是否使用SSL緩沖來加速FTP操作期間的數據傳輸。如果您遇到FTPS/SSL文件傳輸的隨機問題,請關閉此選項。默認值為:FtpsBuffering.Auto。
- ClientCertificates - 在SSL身份驗證過程中使用的X509客戶端證書。了解更多
- ValidateCertificate - 來驗證SSL證書的事件。如果不處理這個事件,並且在驗證證書的時候出現錯誤,那么連接將被終止。
- ValidateAnyCertificate - 接受從服務器接收到的任何SSL證書,並使用ValidateCertificate回調來跳過執行驗證。對於Powershell用戶是很有用的。默認值為:false。
- ValidateCertificateRevocation - 指示在身份驗證期間是否檢查了證書撤銷列表。在需要維護證書鏈的驗證(the certificate chain validation),但跳過證書的撤銷檢查(certificate revocation check)時非常有用。默認值為:true。
- PlainTextEncryption - 使用CCC命令,來使得在連接FTPS后立即禁用加密。當你有一個FTP防火牆需要使用純文本的FTP的時候,這個是很有用的,但是你的服務器要授權FTPS的連接。默認值為:false。
文件清單列表設置
- ListingParser - 要使用的文件清單列表解析器。基於服務器類型會自動的計算,除非被更改。文件列表解析在2017年得到了改進,但是要使用舊的解析例程,請使用FtpParser.Legacy。
- ListingCulture - 用於解析文件清單的區域性。默認值為:CultureInfo.InvariantCulture。
- TimeConversion - 控制如何轉換服務器返回的時間戳。默認設置假定所有服務器都返回UTC。默認值為:DateTimeStyles.AssumeUniversal。
- TimeOffset - 服務器和客戶機之間的時差,以小時為單位。如果服務器位於阿姆斯特丹,而您在洛杉磯,則時差為9小時。默認值為:0。
- RecursiveList - 如果你的服務器支持一個遞歸的LIST命令,使用預定義的邏輯進行檢查。如果您確定您的服務器支持遞歸列表,請將此設置為true。(LIST -R)
- BulkListing - 如果為真,則通過一次讀取文件清單的多行來提高GetListing的性能。如果為false,則GetListing將逐行讀取文件清單。如果GetListing在您的服務器上會有問題,那么請設置為false。默認值為:true。
- BulkListingLength - 在GetListing期間要讀取的字節。只有在BulkListing為true的時候才會被執行。默認值為:128。
- MaximumDereferenceCount - 在放棄之前,DereferenceLink()將遵循的符號鏈接的最大遞歸深度。默認值為:20。
文件傳輸設置
- RetryAttempts - 在下載或上傳過程中發生驗證失敗時允許重試的次數。默認值為:1。
- TransferChunkSize - 在上傳/下載文件的時候所使用的塊的大小(以字節為單位)。默認值為:65536(65KB)。
- UploadRateLimit - 上傳速度的限制(以kbyte/s為單位),在高級API中被使用。默認值為:0(無限制)。
- DownloadRateLimit - 下載速度的限制(以kbyte/s為單位),在高級API中被使用。默認值為:0(無限制)。
- UploadDataType - 上傳文件以ASCII模式還是二級制模式。默認值為:FtpDataType.Binary。
- DownloadDataType - 下載文件以ASCII模式還是二級制模式。默認值為:FtpDataType.Binary。
- NoopInterval - 在發送NOOP命令之間等待的時間(以毫秒為單位),以便在長時間的文件傳輸期間保持控制套接字處於活動狀態。將這個間隔設置得太低會對性能產生負面影響。將這個間隔設置為0將完全禁用NOOP命令。如果在文件傳輸期間超時,請減少此設置。請閱讀此屬性的建議值的PR說明。默認值為:15000(15秒)。
超時設置
- ConnectTimeout - 在放棄之前,等待連接成功的時間(單位毫秒)。默認值為:15000(15秒)。
- ReadTimeout - 在放棄之前,從底層流讀取數據的等待時間(單位毫秒)。默認值為:15000(15秒)。
- DataConnectionConnectTimeout - 在放棄之前,等待數據連接建立的時間(單位毫秒)。默認值為:15000(15秒)。
- DataConnectionReadTimeout - 在放棄之前,等待服務器通過數據通道發送數據的時間(單位毫秒)。默認值為:15000(15秒)。
- SocketPollInterval - 在調用套接字上的Poll()以測試連接之前,從上一次套接字活動到開始必須經歷的時間(單位毫秒)。將這個間隔設置得太低會對性能產生負面影響。將此間隔設置為0將完全禁用輪詢(Poll)。默認值為:15000(15秒)。
嵌套字(socket)設置
- SocketKeepAlive - 設置SocketOption.KeepAlive在將來所有的流的套接字上使用。默認值為:false
- StaleDataCheck - 檢查在套接字上是不是有過時的數據(沒有被請求的數據)。在某些情況下,控制連接可能會超時,但是在服務器關閉連接之前,它可能會發送一個4xx的意外的響應,並且會以匯報導致同步的錯誤。為了避免這個問題,Execute()方法在執行命令之前檢查套接字上是否有可用的數據。默認值為:true。
- EnableThreadSafeDataConnections - 為每個文件的下載和上傳創建一個新的FTP連接。這是一種較慢但線程安全的方法,可使單個控制連接上的異步操作透明。如果FTP服務器每個用戶名只允許一個連接,則將此設置為false。了解更多。默認值為:false。
FTP支持
映射表記錄了支持的FTP命令和相應的API..
連接指令
指令 |
API |
描述 |
HOST |
SendHost和SendHsotDomain |
在共享主機上標識您的域 |
USER、PASS |
Credentials |
使用用戶名和密碼登錄 |
QUIT |
Disconnect() |
斷開連接 |
PASV、EPSV、EPRT |
DataConnectionType |
被動和主動的FTP模式 |
FEAT |
HasFeature() |
獲取服務器支持的特性 |
SYST |
GetSystem() |
獲取服務器系統類型 |
OPTS UTF8 ON |
Encoding |
支持utf-8文件名 |
OPTS UTF8 OFF |
Encoding,DisableUTF8() |
禁用utf-8文件名 |
SUTH TLS |
EncryptionMode |
切換到TLS/FTPS |
PBSZ、PROT |
EncryptionMode和 DataConnectionEncryption |
配置TLS/FTPS連接 |
CCC |
PlainTextEncryption |
切換到純文本FTP |
PRET |
Automatic |
預傳輸(Pre-transfer)文件信息 |
TYPE A |
UploadDataType和 DownloadDataType |
使用ASCII編碼傳輸數據 |
TYPE I |
UploadDataType和 DownloadDataType |
使用二進制編碼傳輸數據 |
文件管理命令
命令 |
API |
描述 |
MLSD |
GetListing() |
獲得目錄的機器列表 |
LIST |
使用FtpListOption.ForceList標志位的GetListing() |
獲取目錄文件列表 |
NLST |
GetNameList() 使用FtpListOption.ForceNameList標志位的GetListing() |
獲取目錄名列表 |
LS |
使用FtpListOption.UseLS標志位的GetListing() |
獲取目錄文件列表 |
STAT |
使用FtpListOption.UnsStat標志位的GetListing() |
獲取目錄文件列表 |
MLST |
GetObjectInfo() |
獲得文件信息 |
DELE |
DeleteFile() |
刪除一個文件 |
MKD |
CreateDirectory() |
創建一個目錄 |
SITE MKDIR |
CreateDirectory() |
服務器端遞歸創建一個目錄(ProFTPD) |
RMD |
DeleteDirectory() |
刪除一個目錄 |
SIT RMDIR |
DeleteDirectory() |
服務器端遞歸刪除一個目錄(ProFTPD) |
RMDA |
DeleteDirectory() |
服務器端遞歸刪除一個目錄(Serv-U) |
CWD |
SetWorkingDirectory() |
改變工作目錄 |
PWD |
GetWorkingDirectory() |
獲得工作目錄 |
SIZE |
GetFileSize() |
獲得文件的字節大小 |
MDTM |
GetModifiedTime() 使用FtpListOption.Modify標志位的GetListing() GetObjectInfo()的dateModified |
獲得文件的修改日期 |
MFMT |
SetModifiedTime() |
修改文件的修改日期 |
SITE CHMOD |
Chmod()或者SetFilePermissions() |
修改文件的權限 |
RNFR、RNTO |
Rename() MoveFile() |
重命名一個文件或一個目錄 移動一個文件和一個目錄 |
NOOP |
Upload() UploadFile() Download() DownloadFile() |
在文件傳輸的時候保持活動狀態 |
文件哈希命令
命令 |
API |
描述 |
HASH |
GetHash() |
獲取一個文件的哈希值 |
OPTS HASH |
GetHashAlgorithm()/SetHashAlgorithm() |
為哈希命令選擇一個哈希算法 |
MD5 |
GetChecksum()或GetMD5() |
獲得一個文件的MD5哈希值 |
XMD5 |
GetChecksum()或GetXMD5() |
獲得一個文件的MD5哈希值 |
XSHA1 |
GetChecksum()或GetXSHA1() |
獲得一個文件的SHA-1哈希值 |
XSHA256 |
GetChecksum()或GetXSHA256() |
獲得一個文件的SHA-256哈希值 |
XSHA512 |
GetChecksum()或GetXSHA512() |
獲得一個文件的SHA-512哈希值 |
常見問題
如何自動檢測正確的鏈接設置?
使用下面的代碼:
FtpClient client = new FtpClient(hostname, username, password);//或者設置Host和Credentials var profiles = client.AutoDetect(); //如果找到任何配置文件,將代碼打印到控制台 if(profiles.Count > 0){ var code = profiles[0].ToCode(); Console.WriteLine(code); }
一旦你找一個工作連接配置文件后,使用生成的代碼快速連接到你的FTP服務器。
如何自動連接到FTP或FTPS服務器?
使用下面的代碼:
FtpClient client = new FtpClient(hostname, username, password);//或者設置Host和Credentials client.AutoConnect();
如何連接SSL/TLS?/如何使用FTPS?
使用下面的代碼:
FtpClient client = new FtpClient(hostname, username, password);//或者設置Host和Credentials client.EncryptionMode = FtpEncryptionMode.Explicit; client.SslProtocols = SslProtocols.Tls; client.ValidateCertificate += new FtpSslValidation(OnValidateCertificate); client.Connect(); void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e){ //在這里添加邏輯以測試證書是否有效 e.Accept = true; }
如果你連接到服務器有任何的問題,嘗試使用其中之一:
讓操作系統選擇最高和最相關的TLS協議。
client.SslProtocols = Security.Authentication.SslProtocols.None;
防止操作系統使用在.NET Framework中有問題的TLS 1.0。
client.SslProtocols = SslProtocols.Default | SslProtocols.Tls11 | SslProtocols.Tls12;
如果你在Linux上使用並且使用SSL/TLS連接失敗,很可能是這個問題。
如何在使用FTPS時驗證服務器的證書?
方法一:如果SSL證書沒有錯誤則進行連接。
cleint.ValidanteCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidtionEventArgs e){ if(e.PolicyErrors != System.Net.Security.SslPolicyErrors.None) { e.Accept = false; } else { e.Accept = true; } });
方法二:如果證書與白名單證書匹配,則連接。
首先,您必須發現有效證書的字符串。使用此代碼將有效的證書字符串保存到文件中:
cleint.ValidanteCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidtionEventArgs e){ File.WrtieAllText(@”c:\cert.txt”, e.Certificate.GetRawCertDataString()); });
最后,使用這個代碼檢查收到的證書是否與您信任的證書匹配:
string ValidCert = “<insert contents of cert.txt>”; cleint.ValidanteCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidtionEventArgs e){ if(e.PolicyErrors == SslPolicyErrors.None || e.Certificate.GetRawCertDataString() == ValidCert){ e.Accept = true; } else { Throw new Exception(“Invalid certificate : ” + e.PolicyErrors); } });
如何使用SSL/TLS連接到Azure?
假設您在Azure應用程序服務實例上使用FTP發布服務。
如果您在連接Azure時遇到問題,請確保您沒有“只使用FTPS”。根據Azure文檔,“僅支持FTPS”不支持TLS 1.0和1.1,這可能會在試圖將FluentFTP用於較舊版本的Windows時破壞連接。因此,當您試圖連接到一個將會阻塞TLS 1.1的Azure FTP實例時,連接將靜默地失敗,因為它只接受TLS 1.2。
將設置更改為允許不安全的FTP之后,可以使用顯式和隱式SSL模式連接FTPS。
如何連接FTPS,然后切換回純文本(Plaintext)的FTP?
當你有一個FTP防火牆需要使用初文明的FTP的時候這是非常有用的。我們使用CCC命令指示服務器恢復到FTP。
在調用FtpClient類上的Connect()或任何其他方法之前設置此選項。
client.PlainTextEncryption = true;
如何連接SFTP?
SFTP不被支持,因為它是SSH下的FTP,一個完全不一樣的協議。請使用SSH.NET。
如何中使用匿名的FTP賬戶登錄?/我在登錄的時候遇到錯誤但是我可以在Firefox/Filezilla中正常登錄
不設置Credentials屬性,我們可以用匿名的身份登錄。或者您可以手動指定以下內容:
client.Credentials = new NetworkCredential("anonymous", "anonymous");
如何使用FTP代理登錄?
創建一個FtpClientHttpProxy或者FtpClientUserAtHostProxy的對象實例,然后按照往常一樣使用FTP的屬性和方法。
如何追蹤文件的傳輸進度?
所有的高級的方法都提供了一個progress的參數,被使用來跟蹤上傳或者下載的進度。
在使用之前,先創建一個回調的方法來提供給上傳/下載的方法。它將隨着FtpProgress對象被調用,其中包含傳輸的百分比和各種統計數據。
如果你創建在你WinForm程序的UI中,可以創建一個Minimum = 0並且Maximum = 100的ProgressBar。
使用異步的API:
//接受一個FtpProgress對象的回調方法 Progress<FtpProgress> progress = new Progress<FtpProgress>(x => { //當進度未知的時候,會收到-1 if(x.Progress < 0)
{ progressBar.IsIndeterminate = true; } else { progressBar.IsIndeterminate = false; progressBar.Value = x; } });
使用同步的API:
//接受一個FtpProgress對象的回調方法 Action<FtpProgress> progress = new Action<FtpProgress>(x => { //當進度未知的時候,會收到-1 if(x.Progress < 0) { progressBar.IsIndeterminate = true; } else { progressBar.IsIndeterminate = false; progressBar.Value = x; } });
現在要調用上傳/下載方法並提供您剛才創建的新的progress對象。
使用異步的方式:
await client.DownloadFileAsync(localPath, remotePath, FtpLocalExists.Overwrite, FluentFTP.FtpVerify.Retry, progress);
使用同步的方式:
client.DownloadFile(localPath, remotePath, FtpLocalExists.Overwrite, FluentFTP.FtpVerify.Retry, progress);
對於.NET 2.0的用戶,通過IProgress類來實現。你傳遞的對象的Report()方法將會攜帶進度的值被調用。
如何上傳動態創建的數據?
使用Upload()來上傳一個stream或者byte[]。
如何下載數據而不將其保存到磁盤?
使用Download()將數據下載到一個stream或者byte[]中。
如何繼續下載一個文件?
使用帶有existsMode設置為FtpLocalExists.Append的DownloadFile()或者DownloadFiles()。
//通過比較文件大小和本地文件的大小,只下載文件中缺少的部分 client.DownloadFile(@”C:\MyVideo.mp4”, “/htdocs/MyVideo.mp4”, FtpLocalExists.Append);
其他的配置:
- FtpLocalExists.Skip - 如果本地文件存在,我們將盲目地跳過下載,而不進行任何檢查。
- FtpLocalExists.Overwrite - 如果本地文件存在,則重新啟動下載並覆蓋該文件。
- FtpLocalExists.Append - 如果本地文件存在,我們通過檢查本地文件大小來恢復下載,並將丟失的數據追加到文件中。
如何繼續上傳一個文件?
使用一個新的API UploadFile():
//通過比較文件大小和本地文件的大小,只上傳服務器文件中缺少的部分 client.UploadFile(@”C:\bigfile.iso”, “/htdocs/bigfile.iso”, FtpLocalExists.Append);
如何控制上傳和下載的速度?
設置UploadRateLimit和DownloadRateLimit屬性來控制數據傳輸的速度。只有高級API才支持同步和異步版本,比如:
- Upload()/Download()
- UploadFile()/DownloadFile()
- UploadFiles()/DownloadFiles()
有關節流的最新改進,請參閱這篇文章。
如何驗證文件的哈希值/校驗和,如果校驗和不匹配,如何重試?
將FtpVerify選項設置添加到UploadFile()或DownloadFile()以啟用自動校驗和驗證。
//上傳文件的時候重新嘗試設置為3次 client.RetryAttempts = 3; //上傳一個文件,在放棄之前或嘗試重傳3次 client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/MyVideo.mp4", FtpExists.Overwrite, false, FtpVerify.Retry);
所有可能的配置:
- FtpVerify.OnlyChecksum - 驗證校驗和,根據成功返回真/假。
- FtpVerify.Delete - 驗證校驗和,如果不匹配就刪除目標文件。
- FtpVerify.Retry - 驗證校驗和,重試復制X次,然后放棄。
- FtpVerify.Retry | FtpVerify.Throw - 驗證校驗和,重試復制X次,如果仍然不匹配則拋出錯誤。
- FtpVerify.Retry | FtpVerifyDelete - 驗證校驗和,重試復制X次,如果仍然不匹配就刪除目標文件。
- FtpVerify.Retry | FtpVerifyDelete | FtpVerify.Throw - 驗證校驗和,重試復制X次,如果仍然不匹配就刪除目標文件,然后拋出一個錯誤
如何追加到一個文件?
使用API Upload():
//將數據追加到一個已經存在的文件中 File.AppendAllText(@"C:\readme.txt", "text to be appended" + Environment.NewLine); //只有readme.txt的新部分將被寫入服務器 client.UploadFile("C:\readme.txt", "/htdocs/readme.txt", FtpExists.Append);
使用基於流的API OpenAppend():
using (FtpClient conn = new FtpClient()) { conn.Host = "localhost"; conn.Credentials = new NetworkCredential("ftptest", "ftptest"); using (Stream ostream = conn.OpenAppend("/full/or/relative/path/to/file")) { try { ostream.Position = ostream.Length; var sr = new StreamWriter(ostream); sr.WriteLine(...); } finally { ostream.Close(); conn.GetReply(); //從服務器讀取成功/失敗響應 } } }
如何使用低級的(low-level)API下載文件?
使用API OpenRead():
//創建遠程FTP流和本地文件流 using (var remoteFileStream = client.OpenRead(remotePath, FtpDataType.Binary)){ using (var newFileStream = File.Create(localPath)){ //一次讀取8KB的數據(你可以增加數量) byte[] buffer = new byte[8 * 1024]; //下載文件到本地的流 int len; while ((len = remoteFileStream.Read(buffer, 0, buffer.Length)) > 0) { newFileStream.Write(buffer, 0, len); } } } //讀取FTP響應並防止套接字上的過時數據 client.GetReply();
如果我的服務器不支持UTF-8,如何上傳/下載Unicode文件名的文件?
手動設置連接編碼,以確保特殊字符正常工作。
默認你應該使用的代碼頁(codepage)是1252 Windows Western。它支持英語+歐洲字符(重音字符)。
client.Encoding = System.Text.Encoding.GetEncoding(1252); //ANSI代碼頁1252(Windows Western)
以下是基於你需要的字符集的代碼頁的完整列表:
- 874 – English + Thai
- 1250 – English + Central Europe
- 1251 – English + Cyrillic (Russian)
- 1252 – English + European (accented characters)
- 1253 – English + Greek
- 1254 – English + Turkish
- 1255 – English + Hebrew
- 1256 – English + Arabic
- 1257 – English + Baltic
- 1258 – English + Vietnamese
GetListing()如何在內部工作?
- 當你調用GetListing(),如果它們被服務器支持,FluentFTP首先會想要去使用機器列表清單(使用MLSD命令)。這些數據是最准確的,並且你可以獲取正確的文件大小和修改日期(UTC)。你可以使用client.ListingParser = FtpParser.Machine來強制使用這個模式,並且使用FtpListOption.ForceList標志來禁用它。您還應該包括FtpListOption.Modify標志來獲得最精確修改日期(精確到第二個)。
- 如果機器列表清單不被支持,我們退一步使用下面列出的特定於服務器OS的解析器(LIST命令)。你可以強制地使用一個特定的解析器,通過使用client.ListingParser = FtpParser.*。
- Unix解析器:用於例如Pure-FTPd、ProFTPD、vsftpd。如果遇到錯誤,通過使用client.ListingParser.UnixAlt,你可以嘗試使用另一種Unix解析器。
- Windows解析器:用於例如IIS、DOS、Azure、FileZilla服務器。
- VMS解析器:用於例如Vax、VMS、OpenVMS。
- NonStop解析器:用於例如Tandem、HP NonStop Guardian。
- IBM解析器:用於列入IBM OS/400。
如果這些都不能滿足你,你還可以退一步使用名稱清單列表(NLST命令),它比LIST和MLSD命令要慢很多。這是因為NLST只發送文件名列表,沒有任何屬性。必須逐個文件地查詢服務器的文件大小、修改日期和類型(文件/文件夾)。通過FtpListOption.ForceNameList標志,可以讓名稱清單列表可以被強制使用。
筆記:一些FTP服務器在列空文件夾的列表清單的時候不返回應答,所以客戶端在另一端將沒有與服務器溝通的套接字。這些異常在內部被捕獲,並返回一個空的文件列表。如果你需要檢查這個的捕獲的實現,請在FluentFTP項目中搜索FtpMissingSocketException的所有實例。
GetListing()如何返回一個遞歸的文件列表?
在就版本的FluentFTP中,我們假定所有的服務器都支持通過List -R命令來遞歸列出文件的列表清單。然而,這導致了各種FTP服務器布置成遞歸列出清單的許多的問題:GetListing()調用將簡單地返回第一個目錄的內容,而不包含任何子目錄。
因此,自從20.0.0版本,我們嘗試去檢查FTP服務器的軟件,並且如果我們確定它不支持遞歸列表,我們將自己動手地進行遞歸。我們開始先假設所有服務器都不支持遞歸列表,然后將特定的服務器類型列入白名單。
如果您感覺GetListing()在使用遞歸列出列表清單的時候速度太慢,並且您知道您的FTP服務器支持LIST -R命令,然后請為您的服務器提供支持:
- 找到FtpServer枚舉中存在的FTP服務器類型。
- 將FtpClient.RecursiveList()更新為您的服務器類型返回為true。
支持哪種散列命令?
我們支持XCRC、XMD5和XSHA,它們是非標准命令,不包含任何形式的規范。它們不能保證工作,強烈建議您檢查FtpClient。在調用這些方法之前,為各自的標志設置功能標志(XCRC、XMD5、XSHA1、XSHA256、XSHA512)。
這里文章中描述的MD5命令支持也已經被添加。在執行命令之前,再次檢查FtpFeature.MD5。
對HASH命令的支持已經添加到FluentFTP中。它支持從支持這個功能的服務器上檢索SHA-1、SHA-256、SHA-512和MD5散列。返回的FtpHash對象,它有一個具有針對給定流或本地文件檢查結果的方法。你可以在這個草案中了解更多關於HASH的信息。
如何在調試時追蹤FTP命令?
在程序啟動時執行此操作(因為它是靜態的,所以對所有FtpClient實例都有效)。
.NET Framework版本
FtpTrace.AddListener(new ConsoleTraceListener()); FtpTrace.LogUserName = false;//隱藏FTP用戶名 FtpTrace.LogPassword = false;//隱藏FTP密碼 FtpTrace.LogIP = false; //隱藏FTP的IP地址
.NET Standard版本
FtpTrace.LogToConsole = true; FtpTrace.LogUserName = false;//隱藏FTP用戶名 FtpTrace.LogPassword = false;//隱藏FTP密碼 FtpTrace.LogIP = false;//隱藏FTP的IP地址
如何在調試記錄所有的FTP命令到文件中?
在程序啟動時執行此操作(因為它是靜態的,所以對所有FtpClient實例都有效)。
.NET Framework版本
FtpTrace.AddListener(new TextWriterTraceListener("log_file.txt")); FtpTrace.LogUserName = false;//隱藏FTP用戶名 FtpTrace.LogPassword = false;//隱藏FTP密碼 FtpTrace.LogIP = false; //隱藏FTP的IP地址
.NET Standard版本
FtpTrace.LogToFile = “log_file.txt”; FtpTrace.LogUserName = false;//隱藏FTP用戶名 FtpTrace.LogPassword = false;//隱藏FTP密碼 FtpTrace.LogIP = false;//隱藏FTP的IP地址
如何將關鍵錯誤記錄到文件中?
這是生產服務器的推薦配置。僅在.NET Framework版本中被支持。
在程序啟動時執行此操作(因為它是靜態的,所以對所有FtpClient實例都有效)。
FtpTrace.LogFunctions = false; FtpTrace.AddListener(new TextWriterTraceListener("log_file.txt"){ Filter = new EventTypeFilter(SourceLevels.Error) });
如何禁用函數調用的日志記錄?
在程序啟動時執行此操作(因為它是靜態的,所以對所有FtpClient實例都有效)。
FtpTrace.LogFunctions = false;
如何中日志中省略掉敏感的信息?
使用這些設置來控制日志中包含哪些數據:
- FtpTrace.LogUserName - 是否記錄FTP的用戶名
- FtpTrace.LogPassword - 是否記錄FTP的密碼
- FtpTrace.LogIP - 是否記錄FTP的服務器IP地址
如何使用像NLog這樣的第三方日志記錄框架?
FluentFTP有一個名為“FluentFTP”的內置TraceSource,可用於調試和日志記錄。目前,除了.NET Standard之外,所有的.NET Framework版本都可以使用。通過寫入到程序或者配置到你的app.config或者web.config都可以將實現任何的TraceListener附加到類庫程序中。這將允許直接日志記錄或轉發到第三方日志記錄框架。
大多數跟蹤消息的類型為Verbose或Information,通常可以忽略,除非進行調試。大多數被忽略的異常被歸類為Warning,但是返回布爾值表示成功/失敗的方法,將以Error級別記錄失敗原因。如果您使用的是.NET Standard,並且設置了DEDUG標志,然后所有日志消息將通過Debug.Write(message)方式發出。
在代碼中附加TraceListener:
TraceListener console = ConsoleTraceListener() { Filter = new EventTypeFilter(SourceLevels.Verbose | SourceLevels.ActivityTracking) }; FtpTrace.AddListener(console);
通過配置文件附加:
<system.diagnostics> <trace autoflush="true"></trace> <sources> <source name="FluentFTP"> <listeners> <clear /> <!--附加一個Console控制台監聽器--> <add name="console" /> <!--附加一個File監聽器--> <add name="file" /> <!--附加一個用戶自定義的監聽器--> <add name="myLogger" /> <!--附加一個NLog監聽器--> <add name="nlog" /> </listeners> </source> </sources> <sharedListeners> <!--定義一個Console控制台監聽器--> <add name="console" type="System.Diagnostics.ConsoleTraceListener" /> <!--定義一個File監聽器 --> <add name="file" type="System.Diagnostics.TextWriterTraceListener" initializeData="outputFile.log"> <!--只寫入錯誤--> <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error" /> </add> <!--定義一個用戶自定義的監聽器--> <add name="custom" type="MyNamespace.MyCustomTraceListener /> <!--附加一個NLog監聽器--> <add name="nlog" type="NLog.NLogTraceListener, NLog" /> </sharedListeners> </system.diagnostics>
EnableThreadSafeDataConnections做什么?
EnableThreadSafeDataConnections是由最初的作者構建的一個較老的特性。如果為true,那么每當您試圖上傳/下載文件時,它都會打開一個新的FTP客戶端實例(並重新連接到服務器)。它曾經是默認設置,但它嚴重影響了性能,所以我禁用了它,發現許多問題都得到了解決,性能也得到了恢復。我相信如果開發者想要多線程上傳,他們應該啟動一個新的BackgroundWorker並在該線程中創建/使用FtpClient。如果你想要並發上傳,可以嘗試一下。
如何對FluentFTP做一些修改?/如何提交一個拉取請求(a pull reqest)?
首先你必須“fork”FluentFTP,然后對本地版本進行更改,當提交“pull request”請求讓我合並你的變化。
- 在這個頁面的右上角點擊Fork
- 在這里打開你的版本:https://github.com/YOUR_GITHUB_USERNAME/FluentFTP
- 下載Github Desktop並登錄你的賬戶
- 點擊File > Clone repository... 並且在列表中選擇FluentFTP
- 將想要放置源碼的地方,編輯到“本地的路徑”,並且點擊Clone
- 使用Visual Studio 2017 Community以及更高的版本來對項目進行編輯
- 切換到Github桌面,它現在應該會顯示已更改文件的列表
- 輸入一個提交的總結記錄(左下方),然后點擊Commit
- 點擊Push to origin(右上方)
- 打開拉取請求頁面來創建一個PR
- 點擊New pull request(右上方)
- 點擊compare across forks(藍色的鏈接,右上方)
- 在右邊的“head fork”中選擇您的用戶名
- 點擊Create pull request
- 總結你在標題中所做的修改
- 鍵入有關您在描述中所做更改的詳細信息
- 點擊Create pull request
- 謝謝!
如何檢測正在連接的服務器的類型?
您可以讀取ServerType來獲得您所連接的FTP服務器軟件的確切類型。我們動態根據我們接連到服務器時服務器所發送的歡迎信息(the welcome message),來檢測FTP服務器軟件。我們目前可以檢測如下軟件類型:
- PureFTPd
- VsFTPd
- ProFTPD
- WuFTPd
- FileZilla Server
- OpenVMS
- Windows Server/IIS
- Windows CE
- GlobalScape EFT
- HP NonStop/Tandem
- Serv-U
- Cerberus
- CrushFTP
- glFTPd
- Homegate FTP
- BFTPd
- FTP2S3 Gateway
- XLight
- Solaris FTP
- IBM z/OS
您還可以讀取ServerOS來獲得所連接的FTP服務器的操作系統。我們可以檢測如下系統到:
- Windows
- Unix
- VMS
- IBM OS/400
- IBM z/OS
- SunOS
如何使用客戶端證書登入FTPS?
添加你的證書到ClientCertificates,然后再調用Connect()。
client.EncryptionMode = FtpEncryptionMode.Explicit; client.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; client.SocketKeepAlive = false; client.ClientCertificates.Add(new X509Certificate2("C:\mycert.cer")); client.ValidateCertificate += (control, e) => { e.Accept = e.PolicyErrors == SslPolicyErrors.None; }; client.Connect();
並確保:
- 您使用的是X509Certificate2對象,而不是不完整的X509Certificate實現。
- 您不使用pem證書,而是使用p12。請查看這篇Stack Overflow thread來獲得更多信息。如果您獲得的SPPI異常中包含關於意外消息或格式錯誤消息的內部異常,您可能使用了錯誤類型的證書。
如何從一個文件捆綁X509證書?
您需要將證書添加到本地存儲(local store),然后執行以下操作:
FluentFTP.FtpClient client = new FluentFTP.FtpClient("WWW.MYSITE.COM", "USER","PASS"); //選擇證書並將它添加到客戶端 X509Store store = new X509Store("MY", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Select a certificate", "Select a certificate", X509SelectionFlag.MultiSelection); if (scollection.Count != 1) { throw new Exception("Error: You have not chosen exactly one certificate"); } foreach (X509Certificate2 x509 in scollection) { client.ClientCertificates.Add(x509); } store.Close(); //client.ReadTimeout = 10000; client.Connect();
這是另外一種方式。使用X509Certificate2。我一直無法讓X509Certificate證書工作,從我的查閱的資料來看,這是因為它是一個不完整的實現。
public void InitSFTP() { FluentFTP.FtpClient client = new FluentFTP.FtpClient("WWW.MYSITE.COM", "USER", "PASS"); X509Certificate2 cert_grt = new X509Certificate2("C:\mycert.xyz"); client.EncryptionMode = FtpEncryptionMode.Explicit; client.DataConnectionType = FtpDataConnectionType.PASV; client.DataConnectionEncryption = true; client.ClientCertificates.Add(cert_grt); client.ValidateCertificate += new FtpSslValidation(OnValidateCertificate); client.Connect(); } private void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e) { e.Accept = true; }
解決問題
在Visual Studio 2010中Fluent安裝失敗:“System.Runtime”已經為“FluentFTP”定義了一個依賴項
你的VS使用了一個老版本的nuget.exe,所以它不能正確安裝最新的FluentFTP。你必須下載nuget.exe 並手動執行下面這些命令:
cd D:\Projects\MyProjectDir
C:\Nuget\nuget.exe install FluentFTP
上傳一個帶有特殊字符的文件,像是“Caffè.png”,在FTP服務器上,它表現為“Caff?.png”。這個服務器只支持ASCII,但是這個“è”是ASCII。FileZilla可以上傳這個文件,並且沒有任何問題
手動設置連接編碼,以確保特殊字符正常工作。
默認你應該使用的代碼頁(codepage)是1252 Windows Western。它支持英語+歐洲字符(重音字符)。
client.Encoding = System.Text.Encoding.GetEncoding(1252); //ANSI代碼頁1252(Windows Western)
如何文件名中含有俄文字母,我無法刪除這個文件。但是FileZilla可以刪除這個文件,並且沒有問題
手動設置連接編碼,以確保特殊字符正常工作。
對於俄語,你需要使用代碼頁1251 Windows Cyrillic
client.Encoding = System.Text.Encoding.GetEncoding(1251); //ANSI代碼頁1251(Windows Cyrillic)
我總是在我的Azure WebApp中發生TimeoutException異常
首先嘗試減少Azure需要的套接字輪詢間隔。
client.SocketPollInterval = 1000;
如果這也不管用,那么試着減少超時時間。
client.SocketPollInterval = 1000; client.ConnectTimeout = 2000; client.ReadTimeout = 2000; client.DataConnectionConnectTimeout = 2000; client.DataConnectionReadTimeout = 2000;
如果這些都不起作用,請記住Azure有一個間歇性的bug,在這個bug中,它會在FTP請求期間更改ip地址。連接是使用IP地址A建立的,Azure使用IP地址B進行數據傳輸,這在很多防火牆上是不允許的。這是一個已知的Azure bug。
許多的命令無法在Windows CE上正常工作
根據MSDN上所說的,Windows CE上的FTP實現是最少的,並通過源代碼開放定制。許多高級命令如CHMOD都不受支持。
使用OpenWrite/OpenAppend成功傳輸單個文件后,后續文件失敗,出現一些隨機錯誤,如“格式錯誤的PASV響應”
您需要在傳輸完文件之后調用FtpReply status = GetReply(),以確保沒有遺留過時的數據,以免打亂后續命令。
在FTPS的登入期間,SSL協商非常緩慢
FluentFTP在.NET Framework的底層使用SslStream。SslStream使用一個windows的特性功能來動態地更新Root CA證書,這可能會導致證書認證過程中的長時間延遲。這可能會在FluentFTP中引起與SocketPollInterval屬性相關的問題,該屬性用於檢查客戶機和服務器之間的不合理斷開連接。這個MSDN博客討論了SslStream的問題,並討論了如何禁用Root CA證書的自動更新。
FluentFTP記錄認證所需的時間。如果您認為自己正遭受這個問題的困擾,那么請查看Examples\ debug .cs以獲取有關檢索調試信息的信息。
無法從傳輸連接讀取數據:遠程主機強制關閉了現有連接
這意味着服務器上的 [FTP守護進程(FTP daemon)] 服務沒有運行(可能不是這種情況),或者服務當前仍然忙於執行另一個操作。這聽起來就像服務器返回一條消息,表明它仍然在執行上一個操作。
嘗試減少輪詢間隔以確保連接不會超時。
client.SocketPollInterval = 1000;