以下是使用Visual Studio 2005 C #所寫的FTP 上傳/下載及取得清單的程式範例,而這個的.Net Framework需為2.0或以上.
首先,大至上講解一下,在使用FTP時,所以使用到的幾個FTP物件FtpWebRequest,FtpWebResponse,WebRequestMethods. 這四個為FTP中,較為重要的幾個(當然範例中也有用到Stream,FileStream,StreamReader,NetworkCredential, WebRequest但這幾個並非是FTP才會用到的,所以不做特別介紹,如果需要瞭解,可點取連結至MSDN參考說明).其中以FtpWebRequest, FtpWebResponse, WebRequestMethods這三個物件為.Net 2.0才有的,1.0,1.1並沒有.
FtpWebRequest主要就能與FTP伺服器產生互動的功能,例如設定Timeout逾時設定,KeepAlive保持連線,EnableSsl設定是否使用SSL連線,Credential通訊協定認證,GetResponses取得伺服器回應,GetRequestStream用來上載至伺服器的資料流等,看到這個地方,大概就能知道,這一個物件是用來上傳使用的,並且設定其通訊協定.
而另一個物件FtpWebResponse,主要是用來取得伺服器對要求的回應,像是StatusCode取得FTP伺服器回傳最新的狀態碼,WelcomeMessage驗證完成後,所取得到的文字,LastModified取得FTP伺服器上的檔案最近的修改日期及時間,GetResponseStream擷取FTP伺服器回應的資料流(簡單的說,就是下載).
WebRequestMethods,用來設定通訊協定的命令,這樣看起來似乎很難懂,當我們在宣告FtpWebRequest時,就需要設定Method,舉例來說:
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(listUrl);
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; //用來取得目錄的檔案清單
listRequest.Method = WebRequestMethods.Ftp. UploadFile;//上傳檔案
listRequest.Method = WebRequestMethods.Ftp. DownloadFile;//上傳檔案
由此大概就可以知道,它是在設定FtpWebRequest傳送至FTP伺服器的命令.當然也包含DeleteFile刪檔,Rename更名…等.
以上三個FtpWebRequest,FtpWebResponse,WebRequestMethods的更多詳細用法,請參考Visual Studio 2005的Help.
接下來就要帶到,如何用C#寫出下載,上傳及取得清單的方法 :
1. 下載程式範例
internal bool Download(string downloadUrl,string TargetPath, string UserName, string Password)
{//downloadUrl下載FTP的目錄ex : ftp//127.0.0.1/abc.xml , TargetPath本機存檔目錄,UserName使用者FTP登入帳號 , Password使用者登入密碼
Stream responseStream = null;
FileStream fileStream = null;
StreamReader reader = null;
try
{
FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(downloadUrl);
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile; //設定Method下載檔案
if (UserName.Length > 0)//如果需要帳號登入
{
NetworkCredential nc = new NetworkCredential(UserName, Password);
downloadRequest.Credentials = nc;//設定帳號
}
FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse();
responseStream = downloadResponse.GetResponseStream();//取得FTP伺服器回傳的資料流
string fileName = Path.GetFileName(downloadRequest.RequestUri.AbsolutePath);
if (fileName.Length == 0)
{
reader = new StreamReader(responseStream);
throw new Exception(reader.ReadToEnd());
}
else
{
fileStream = File.Create(TargetPath+@"\"+fileName);
byte[] buffer = new byte[1024];
int bytesRead;
while (true)
{//開始將資料流寫入到本機
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
fileStream.Write(buffer, 0, bytesRead);
}
}
return true;
}
catch (IOException ex)
{
throw new Exception(ex.Message);
}
finally
{
if (reader != null)
reader.Close();
else if (responseStream != null)
responseStream.Close();
if (fileStream != null)
fileStream.Close();
}
}
2. 上傳程式範例
internal bool Upload(string fileName, string uploadUrl,string UserName,string Password)
{//fileName上傳的檔案ex : c:\abc.xml , uploadUrl上傳的FTP伺服器路徑ftp://127.0.0.1,UserName使用者FTP登入帳號 , Password使用者登入密碼
Stream requestStream = null;
FileStream fileStream = null;
FtpWebResponse uploadResponse = null;
try
{
FtpWebRequest uploadRequest = (FtpWebRequest)WebRequest.Create(uploadUrl);
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;//設定Method上傳檔案
uploadRequest.Proxy = null;
if (UserName.Length > 0)//如果需要帳號登入
{
NetworkCredential nc = new NetworkCredential(UserName, Password);
uploadRequest.Credentials = nc; //設定帳號
}
requestStream = uploadRequest.GetRequestStream();
fileStream = File.Open(fileName, 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();
return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (uploadResponse != null)
uploadResponse.Close();
if (fileStream != null)
fileStream.Close();
if (requestStream != null)
requestStream.Close();
}
}
3. 取得清單程式範例
internal Hashtable List(string listUrl,string UserName,string Password)
{//listUrl FTP伺服器路徑ftp://127.0.0.1,UserName使用者FTP登入帳號 , Password使用者登入密碼
StreamReader reader = null;
try
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(listUrl);
if (UserName.Length > 0)//如果需要帳號登入
{
NetworkCredential nc = new NetworkCredential(UserName, Password);
listRequest.Credentials = nc; //設定帳號
}
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;// //設定Method取得目錄資訊
FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse();
reader = new StreamReader(listResponse.GetResponseStream());
Hashtable ht = new Hashtable();
int i=0;
while (reader.Peek()>=0)
{//開始讀取回傳資訊
ht[i] = reader.ReadLine();
i++;
}
return ht;//回傳目前清單
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (reader != null)
reader.Close();
}
}
上面三個程式範例為基本的程式範例,當中當然還可以加入一些判斷,例如最常出錯的就是url,這點要注意的是,URL的最後面不需跟著[ / ],正確的URL : ftp://127.0.0.1 , 錯誤的URL : ftp://127.0.0.1/ ,所以在URL的部份,可以加上這個的判斷,減少因為使用者誤Key,而導致的錯誤結果.