文件傳輸協議 (FTP) 是一個標准協議,可用來通過 Internet 將文件從一台計算機移到另一台計算機。 這些文件存儲在運行 FTP 服務器軟件的服務器計算機上。 然后,遠程計算機可以使用 FTP 建立連接,並從服務器讀取文件或將文件復制到服務器。 FTP 服務器與 HTTP 服務器(即 Web 服務器)的相似之處在於可以使用 Internet 協議與之通信。 但是,FTP 服務器不運行網頁;它只是向/從遠程計算機發送/接收文件。
可以將 Internet 信息服務 (IIS) 配置為作為 FTP 服務器來運行。 這樣,其他計算機便可以連接到服務器並將文件復制到服務器或者從服務器復制文件。 例如,如果您在自己的計算機上承載網站,並且希望允許遠程用戶連接到您的計算機並將他們的文件復制到服務器,則可以將 IIS 配置為充當 FTP 服務器。
本文主要講解一下,在Window的IIS中創建FTP的Site並用C#進行文件的上傳下載。
1): 首先展示一下我的Window環境
2): 在配置環境之前,我們要保證相應的Window的feature都已經開啟了,如下圖所示
3): 打開我們的IIS Manager,在Sites的節點點擊鼠標右鍵,選擇Add FTP Site
4): 接上圖,之后會出現如下視圖,我們可以填寫對應的 FTP site name,然后選擇本地某一個磁盤的folder作為此 FTP site 的 Physical path
5): 填寫好必要的信息之后,我們點擊 Next 進入如下界面,可以看出FTP對應的端口號位21,我們這里選擇了Allow SSL就是對傳輸的內容進行加密【即:所謂的SFTP,但是依舊使用的是FTP協議,這與http和https的關系不完全類似】
【注:引文---我們都知道FTP對應的端口應該是21,為什么又冒出來一個20呢?其實,我們們進行FTP文件傳輸中,客戶端首先連接到FTP服務器的21端口,進行用戶的認證,認證成功后,當我們要傳輸文件時,服務器會開一個端口為20來進行傳輸數據文件,也就是說,端口20才是真正傳輸所用到的端口,端口21只用於FTP的登陸認證。我們平常下載文件時,會遇到下載到99%時,文件不完成,不能成功的下載。其實是因為文件下載完畢后,還要在21端口再行進行用戶認證,而我們下載文件的時間如果過長,客戶機與服務器的21端口的連接會被服務器認為是超時連接而中斷掉,就是這個原因。解決方法就是設置21端口的響應時間。】
6): 接上圖,點擊Next按鈕之后,我們將EricSun_FTP這個用戶賦予對應的權限,之后的程序中我們也用此用戶的信息進行登錄認證
7): 上面的步驟都設置完之后,我們用 ftp://192.168.181.133 【當然了這里要換成你自己環境的 ip 地址】來訪問,會直接映射到我們之前設置的物理地址 E盤的 FTP 文件夾
【如果是第一次訪問的話,會彈出一個界面讓你輸入用戶名和密碼進行認證,這里省略】
【【 更加官方的配置過程我們可以訪問此鏈接:http://msdn.microsoft.com/zh-cn/library/6ws081sa(v=vs.100).aspx 】】
8): 配置好了這樣的一個 FTP site之后,可以用如下C#代碼進行訪問來處理文件的上傳和下載
public static void DownloadByFtp(string uri, MemoryStream stream, bool isInternalAuth, string sftpUserName, string sftpPassword) { if (!uri.Contains("ftp://")) uri = "ftp://" + uri; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); if (!isInternalAuth) request.Credentials = new NetworkCredential(sftpUserName, sftpPassword); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.DownloadFile; request.UseBinary = true; FtpWebResponse response = (FtpWebResponse)request.GetResponse(); Stream responseStream = response.GetResponseStream(); int len = 0; do { byte[] buffer = new byte[2048]; len = responseStream.Read(buffer, 0, buffer.Length); stream.Write(buffer, 0, len); } while (len > 0); responseStream.Close(); response.Close(); stream.Position = 0; } public static void UploadByFtp(string ftpAddress, MemoryStream fileStream, string folderName, string fileName, string sftpUsername, string sftpPassword) { string uri = string.Empty; if (ftpAddress.Contains("ftp://")) { uri = ftpAddress; } else { uri = "ftp://" + ftpAddress; } if (!string.IsNullOrEmpty(folderName)) { uri = uri.TrimEnd('/') + "/" + folderName; } if (!string.IsNullOrEmpty(fileName)) { uri = uri.TrimEnd('/') + "/" + fileName; } FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); request.Credentials = new NetworkCredential(sftpUsername, sftpPassword); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.UploadFile; request.UseBinary = true; request.ContentLength = fileStream.Length; byte[] buffer = fileStream.GetBuffer(); Stream stream = request.GetRequestStream(); stream.Write(buffer, 0, buffer.Length); stream.Close(); }
9): 這里提供了另外一些比較常用的方法,可以根據自己的需要進行對應的調整~~

/// <summary> /// upload the file to ftp server. /// </summary> public void UploadByFtp(string ftpAddress, string filePath, string name) { FileStream fs = null; Stream stream = null; string uri = string.Empty; FileInfo fi = new FileInfo(filePath); if (ftpAddress.Contains("ftp://")) uri = ftpAddress + name; else uri = "ftp://" + ftpAddress + name; try { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.UploadFile; request.UseBinary = true; request.ContentLength = fi.Length; byte[] buffer = new byte[2048]; fs = fi.OpenRead(); stream = request.GetRequestStream(); int len = fs.Read(buffer, 0, buffer.Length); while (len != 0) { stream.Write(buffer, 0, len); len = fs.Read(buffer, 0, buffer.Length); } } catch (Exception e) { throw e; } finally { if (stream != null) stream.Close(); if (fs != null) fs.Close(); } } /// <summary> /// upload the file to ftp server. only for cover image process. /// </summary> public void UploadByFtp(string ftpAddress, MemoryStream fileStream, string fileName) { string uri = string.Empty; if (ftpAddress.Contains("ftp://")) uri = ftpAddress; else uri = "ftp://" + ftpAddress; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri + fileName)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.UploadFile; request.UseBinary = true; request.ContentLength = fileStream.Length; byte[] buffer = fileStream.GetBuffer(); Stream stream = request.GetRequestStream(); stream.Write(buffer, 0, buffer.Length); stream.Close(); } /// <summary> /// delete the file from ftp server by ftp protocol. /// </summary> public void DeleteByFtp(string ftpAddress, string fileName) { string uri = string.Empty; if (ftpAddress.Contains("ftp://")) uri = ftpAddress + fileName; else uri = "ftp://" + ftpAddress + fileName; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.DeleteFile; request.GetResponse().Close(); } public void DownloadByFtp(string uri, MemoryStream stream, bool isInternalAuth) { if (!uri.Contains("ftp://")) uri = "ftp://" + uri; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); if (!isInternalAuth) request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.DownloadFile; request.UseBinary = true; FtpWebResponse response = (FtpWebResponse)request.GetResponse(); Stream responseStream = response.GetResponseStream(); int len = 0; do { byte[] buffer = new byte[2048]; len = responseStream.Read(buffer, 0, buffer.Length); stream.Write(buffer, 0, len); } while (len > 0); responseStream.Close(); response.Close(); stream.Position = 0; } /// <summary> /// create the directory on ftp server. /// </summary> public void CreateDirectory(string ftpAddress, string directory) { string uri = string.Empty; if (ftpAddress.Contains("ftp://")) uri = ftpAddress; else uri = "ftp://" + ftpAddress; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri + directory)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.MakeDirectory; request.GetResponse().Close(); } /// <returns>0: successful; 1: can not delete(e.g. have sub-dirs or sub-files); -1: failure</returns> public int RemoveDirectory(string ftpAddress, string directory) { int result; string uri = string.Empty; if (ftpAddress.Contains("ftp://")) uri = ftpAddress; else uri = "ftp://" + ftpAddress; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri + directory)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.RemoveDirectory; try { request.GetResponse().Close(); result = 0; } catch (WebException we) { if (((FtpWebResponse)we.Response).StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) { result = -1; } else { result = 1; throw we; } } catch (Exception e) { result = 1; throw e; } return result; } public string[] GetFileList(string ftpAddress, string directory, bool isInternalAuth) { string uri = string.Empty; StringBuilder result = new StringBuilder(); if (ftpAddress.Contains("ftp://")) uri = ftpAddress; else uri = "ftp://" + ftpAddress; FtpWebRequest request = null; if (!string.IsNullOrEmpty(directory)) request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri + directory)); else request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); if (!isInternalAuth) request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.ListDirectory; WebResponse response = request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); string line = reader.ReadLine(); while (line != null) { result.Append(line); result.Append("/"); line = reader.ReadLine(); } reader.Close(); response.Close(); if (result.Length > 0) return result.ToString().TrimEnd('/').Split('/'); else return null; } /// <returns>0: exist; -1: not exist; 1: unknown (other cause)</returns> public int IsExist(string ftpAddress, string directory) { string uri = string.Empty; int result; if (ftpAddress.Contains("ftp://")) uri = ftpAddress; else uri = "ftp://" + ftpAddress; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri + directory)); request.Credentials = new NetworkCredential(_username, _password); request.KeepAlive = false; request.Method = WebRequestMethods.Ftp.ListDirectory; try { request.GetResponse().Close(); result = 0; } catch (WebException we) { if (((FtpWebResponse)we.Response).StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) { result = -1; } else { result = 1; throw we; } } catch (Exception e) { result = 1; throw e; } return result; }