最近項目需要對FTP伺服器進行操作,現把實作總結如下:
打算分2篇總結:
第1篇總結Ftp的一些正常的操作實作(例如:上傳,下載下傳,建立,删除,FTP間互傳檔案等操作)
第2篇總結Ftp的操作的一些其他實作(例如:異步上傳,異步下載下傳等其他操作)
Microsoft .NET Framework 2.0新增加了3個類使我們很友善的對檔案傳輸協定(FTP)伺服器進行操作
FtpWebRequest類:實作檔案傳輸協定(FTP)用戶端
public sealed class FtpWebRequest : WebRequest
FtpWebResponse類:封裝檔案傳輸協定(FTP)伺服器對請求的響應
public class FtpWebResponse : WebResponse, IDisposable
WebRequestMethods.Ftp類:表示可與FTP請求一起使用的FTP協定方法的類型,無法繼承此類
public static class Ftp
類關系圖

操作ftp的一般步驟我總結如下:
第一步:WebRequest.Create方法,獲得FtpWebRequest的執行個體
第二步:利用WebRequestMethods.Ftp設定FtpWebRequest的Method屬性,指定使用的FTP協定方法的類型
第三步:設定FtpWebRequest的Credentials屬性,指定使用者名和密碼
第四步:送出請求
第五步:接收響應資料流(有些ftp操作可能沒這一步,例如給檔案夾改名)
第六步:關閉流
下面從幾段代碼來分别展示ftp的不同操作:
1.檔案夾和檔案資訊關鍵知識說明:
a.FtpWebRequest類沒有公開的構造函數,我們通過WebRequest.Create方法,獲得FtpWebRequest的執行個體
b.通過WebRequestMethods.Ftp.ListDirectoryDetails(詳細清單)或者WebRequestMethods.Ftp.ListDirectory(簡短清單)擷取FTP伺服器上的檔案清單
c.請求傳回的資料在GetResponseStream方法傳回的流中
d.字元編碼請用System.Text.Encoding.Default,要不中文名會亂碼
e.FtpWebRequest.Credentials屬性設定登陸使用者名和密碼
f.FtpWebRequest.UseBinary屬性,true,訓示伺服器要傳輸的是二進制資料.false,訓示資料為文本。預設值為true
g.FtpWebRequest.EnableSsl屬性,如果控制和資料傳輸是加密的,則為true.否則為false.預設值為 false
執行個體代碼:
擷取ftp://218.16.229.120上的檔案資訊
Uri uri = new Uri ( "ftp://218.16.229.120" );
FtpWebRequest listRequest = ( FtpWebRequest ) WebRequest.Create ( uri );
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
//listRequest.Method = WebRequestMethods.Ftp.ListDirectory;
string ftpUser = "";
string ftpPassWord = "";
listRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );
FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );
Stream responseStream = listResponse.GetResponseStream ( );
StreamReader readStream = new StreamReader ( responseStream , System.Text.Encoding.Default );
if ( readStream != null )
{
MessageBox.Show ( readStream.ReadToEnd ( ) );
}
MessageBox.Show ( string.Format ( "狀态: {0},{1}" ,listResponse.StatusCode, listResponse.StatusDescription ) );
listResponse.Close ( );
responseStream.Close ( );
readStream.Close ( );
通過WebRequestMethods.Ftp.ListDirectoryDetails(詳細清單)或者WebRequestMethods.Ftp.ListDirectory(簡短清單)傳回的結果是不一樣的.請看圖
利用WebRequestMethods.Ftp.ListDirectoryDetails,readStream.ReadToEnd ( )傳回的字元串比較複雜(不同類型的Ftp會有不同傳回形式的傳回結果),要把裡面的檔案夾和檔案區分列出來比較繁瑣,代碼比較多,是以我沒寫出來,感興趣的朋友可以留言,我可以郵件發送.
2.取ftp登陸身份驗證完成後的歡迎資訊關鍵知識說明:
a.FtpWebResponse.WelcomeMessage屬性擷取身份驗證完成時FTP伺服器發送的消息
擷取ftp://218.16.229.120登陸身份驗證完成後的歡迎資訊
MessageBox.Show ( listResponse.WelcomeMessage );
附加說明:要是FTP伺服器的歡迎資訊帶有中文,運作這段代碼時可能會發生異常(基礎連接配接已經關閉: 伺服器送出了協定).
解決辦法:打更新檔Microsoft .NET Framework 2.0 Service Pack 1
3.重命名目錄關鍵知識說明:
a.WebRequestMethods.Ftp.Rename表示重命名目錄的FTP協定方法
b.FtpWebRequest.RenameTo屬性重命名的新名稱
把ftp://218.16.229.120/上的a目錄重命名為av
Uri uri = new Uri ( "ftp://218.16.229.120/a" );
listRequest.Method = WebRequestMethods.Ftp.Rename;
listRequest.RenameTo = "av";
MessageBox.Show ( listResponse.StatusDescription );
4.删除目錄
關鍵知識說明:
a.WebRequestMethods.Ftp.RemoveDirectory表示移除目錄的FTP協定方法
删除ftp://218.16.229.120上的av檔案夾
Uri uri = new Uri ( "ftp://218.16.229.120/av" );
listRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
FtpWebResponse listResponse = ( FtpWebResponse ) listRequest.GetResponse ( );
5.建立目錄關鍵知識說明:
a.WebRequestMethods.Ftp.MakeDirectory表示在FTP伺服器上建立目錄的協定方法
在ftp://218.16.229.120上建立目錄vb
Uri uri = new Uri ( "ftp://218.16.229.120/vb" );
listRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
6.得檔案大小關鍵知識說明:
a.WebRequestMethods.Ftp.GetFileSize表示要用于檢索FTP伺服器上的檔案大小
b.流資料的長度可以從FtpWebResponse.ContentLength屬性中擷取。
擷取ftp://218.16.229.120上的會議記錄.doc檔案大小
Uri uri = new Uri ( "ftp://218.16.229.120/會議記錄.doc" );
listRequest.Method = WebRequestMethods.Ftp.GetFileSize;
MessageBox.Show ( string.Format ( "檔案大小: {0}" , listResponse.ContentLength ) );
7.删除檔案
a.WebRequestMethods.Ftp.DeleteFile表示要用于删除FTP伺服器上的檔案
删除ftp://218.16.229.120上的工作安排.txt檔案
Uri uri = new Uri ( "ftp://218.16.229.120/工作安排.txt" );
listRequest.Method = WebRequestMethods.Ftp.DeleteFile;
MessageBox.Show ( string.Format ( "Delete status: {0}" , listResponse.StatusDescription ) );
8.上傳檔案
a.WebRequestMethods.Ftp.UploadFile表示将檔案上載到FTP伺服器
b.使用FtpWebRequest對象向伺服器上載檔案,則必須将檔案内容寫入請求流,請求流是通過調用FtpWebRequest.GetRequestStream方法.如果未将屬性設定為UploadFile,則不能擷取流。
c.異步對應方法(FtpWebRequest.BeginGetRequestStream方法和FtpWebRequest.EndGetRequestStream 方法),關于異步上傳的實作我會再寫在下篇總彙中
上載檔案D:\abc.txt到ftp://218.16.229.120上
Stream requestStream = null;
FileStream fileStream = null;
FtpWebResponse uploadResponse = null;
try
Uri uri = new Uri ( "ftp://218.16.229.120/abc.txt" );
FtpWebRequest uploadRequest = ( FtpWebRequest ) WebRequest.Create ( uri );
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
string ftpUser = "";
string ftpPassWord = "";
uploadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );
requestStream = uploadRequest.GetRequestStream ( );
fileStream = File.Open ( @"D:\abc.txt" , FileMode.Open );
byte [ ] buffer = new byte [ 1024 ];
int bytesRead;
while ( true )
{
bytesRead = fileStream.Read ( buffer , 0 , buffer.Length );
if ( bytesRead == 0 )
break;
requestStream.Write ( buffer , 0 , bytesRead );
}
requestStream.Close ( );
uploadResponse = ( FtpWebResponse ) uploadRequest.GetResponse ( );
MessageBox.Show ( "Upload complete." );
finally
if ( uploadResponse != null )
uploadResponse.Close ( );
if ( fileStream != null )
fileStream.Close ( );
if ( requestStream != null )
requestStream.Close ( );
其實利用WebClient.UploadData方法,還有一種更簡單的上傳方法:
WebClient request = new WebClient ( );
request.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );
FileStream myStream = new FileStream ( @"D:\abcd.txt" , FileMode.Open , FileAccess.Read );
byte [ ] dataByte = new byte [ myStream.Length ];
myStream.Read ( dataByte , 0 , dataByte.Length ); //寫到2進制數組中
myStream.Close ( );
request.UploadData ( "ftp://218.16.229.120/abcd.txt" , dataByte );
9.下載下傳檔案關鍵知識說明:
a.WebRequestMethods.Ftp.DownloadFile表示要用于從FTP伺服器下載下傳檔案
b.從FTP伺服器下載下傳檔案時,如果指令成功,所請求的檔案的内容即在響應對象的流中。通過調用FtpWebResponse.GetResponseStream方法,可以通路此流。
從ftp://218.16.229.120上下載下傳檔案儲存到d:\abc.txt
Stream responseStream = null;
StreamReader reader = null;
string downloadUrl = "ftp://218.16.229.120/abc.txt";
FtpWebRequest downloadRequest = ( FtpWebRequest ) WebRequest.Create ( downloadUrl );
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );
FtpWebResponse downloadResponse = ( FtpWebResponse ) downloadRequest.GetResponse ( );
responseStream = downloadResponse.GetResponseStream ( );
fileStream = File.Create ( @"d:\" + "abc.txt" );
bytesRead = responseStream.Read ( buffer , 0 , buffer.Length );
fileStream.Write ( buffer , 0 , bytesRead );
MessageBox.Show ( "Download complete" );
if ( reader != null )
reader.Close ( );
else
if ( responseStream != null )
{
responseStream.Close ( );
}
if ( fileStream != null )
fileStream.Close ( );
其實利用WebClient.DownloadData方法,還有一種更簡單的下載下傳方法:
Uri uri = new Uri ( "ftp://218.16.229.120/abc.txt" );
byte [ ] newFileData = request.DownloadData ( uri.ToString ( ) );
FileStream fs = new FileStream ( @"d:\abc.txt" , FileMode.OpenOrCreate , FileAccess.Write );
fs.Write ( newFileData , 0 , newFileData.Length );
fs.Close ( );
10.2個ftp間傳送檔案
a.在搞懂前面所說下載下傳和上傳知識後,其實很好實作2個ftp間傳送檔案.我們可以把傳送檔案看成是先下載下傳後上傳.把下載下傳的檔案響應流資料寫到上傳檔案請求流中即可.
把ftp://218.58.58.19中"集團公司通知"目錄中的"080124-成本費用科目調整通知.pdf"檔案傳送到ftp://218.16.229.120
string downloadUrl = "ftp://218.58.58.19/集團公司通知/080124-成本費用科目調整通知.pdf";
FtpWebRequest downloadRequest = ( FtpWebRequest ) WebRequest.Create ( downloadUrl );
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
string ftpUser = "download";
string ftpPassWord = "download";
downloadRequest.Credentials = new NetworkCredential ( ftpUser , ftpPassWord );
string uploadUrl = "ftp://218.16.229.120/080124-成本費用科目調整通知.pdf";
FtpWebRequest uploadRequest = ( FtpWebRequest ) WebRequest.Create ( uploadUrl );
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
string ftpUser1 = "exwangsoft";
string ftpPassWord1 = "exwangsoft";
uploadRequest.Credentials = new NetworkCredential ( ftpUser1 , ftpPassWord1 );
FtpWebResponse downloadResponse = ( FtpWebResponse ) downloadRequest.GetResponse ( );
Stream responseStream = downloadResponse.GetResponseStream ( );
Stream fileStream = uploadRequest.GetRequestStream ( );
byte [ ] buffer = new byte [ 1024 ];
int bytesRead;
while ( true )
//讀取ftp://218.58.58.19的響應流資料
bytesRead = responseStream.Read ( buffer , 0 , buffer.Length );
if ( bytesRead == 0 )
break;
//寫到ftp://218.16.229.120的請求流資料中
fileStream.Write ( buffer , 0 , bytesRead );
fileStream.Close ( );
uploadResponse = ( FtpWebResponse ) uploadRequest.GetResponse ( );
MessageBox.Show ( "complete" );