FtpWebRequest 核心類別
.NET Framework 2.0 引入 System.Net.FtpWebRequest,提供原生 FTP 客戶端支援,無需第三方庫。核心步驟:
- 建立請求:`FtpWebRequest.Create(uri)`
- 設定認證:`Credentials = new NetworkCredential(user, pass)`
- 指定操作:`Method = WebRequestMethods.FTP.<操作>`
- 設定傳輸模式:`UseBinary = true`(預設)、`UsePassive = true`(預設)
- 取得請求/回應串流進行資料傳輸
- 關閉串流與回應物件
常用 Method 列舉
| Method | 操作 | 說明 |
| UploadFile | 上傳 | 配合 GetRequestStream() 寫入 |
| DownloadFile | 下載 | 配合 GetResponseStream() 讀取 |
| ListDirectory | 簡易列表 | 僅檔名,每行一個 |
| ListDirectoryDetails | 詳細列表 | 含權限、大小、時間(類似 `ls -l`) |
| DeleteFile | 刪除檔案 | |
| RemoveDirectory | 刪除目錄 | 需為空目錄 |
| MakeDirectory | 建立目錄 | |
| Rename | 重命名 | 需設定 `RenameTo` 屬性 |
| GetFileSize | 取得檔案大小 | 回應 `ContentLength` |
| GetDateTimestamp | 取得修改時間 | |
上傳檔案完整範例
public void Upload(string localFilePath, string remoteFileName) {
FileInfo fi = new FileInfo(localFilePath);
string uri = $"ftp://{FtpServerIP}/{remoteFileName}";
var req = (FtpWebRequest)WebRequest.Create(uri);
req.Credentials = new NetworkCredential(FtpUser, FtpPass);
req.Method = WebRequestMethods.FTP.UploadFile;
req.UseBinary = true;
req.KeepAlive = false; // 傳完即關閉,避免連線佔用
req.ContentLength = fi.Length; // 讓伺服器預知大小
const int BufferSize = 2048;
byte[] buffer = new byte[BufferSize];
using (FileStream fs = fi.OpenRead())
using (Stream rs = req.GetRequestStream()) {
int read;
while ((read = fs.Read(buffer, 0, BufferSize)) > 0) {
rs.Write(buffer, 0, read);
}
}
// 可選:讀取回應確認
using (var resp = (FtpWebResponse)req.GetResponse()) {
Console.WriteLine($"上傳完成: {resp.StatusDescription}");
}
}
下載檔案完整範例
public void Download(string remoteFileName, string localFolder) {
string uri = $"ftp://{FtpServerIP}/{remoteFileName}";
string localPath = Path.Combine(localFolder, remoteFileName);
var req = (FtpWebRequest)WebRequest.Create(uri);
req.Credentials = new NetworkCredential(FtpUser, FtpPass);
req.Method = WebRequestMethods.FTP.DownloadFile;
req.UseBinary = true;
using (var resp = (FtpWebResponse)req.GetResponse())
using (Stream rs = resp.GetResponseStream())
using (FileStream fs = new FileStream(localPath, FileMode.Create)) {
byte[] buffer = new byte[2048];
int read;
while ((read = rs.Read(buffer, 0, buffer.Length)) > 0) {
fs.Write(buffer, 0, read);
}
}
}
取得檔案列表
public string[] ListFiles() {
var req = (FtpWebRequest)WebRequest.Create($"ftp://{FtpServerIP}/");
req.Credentials = new NetworkCredential(FtpUser, FtpPass);
req.Method = WebRequestMethods.FTP.ListDirectory;
req.UseBinary = true;
using (var resp = (WebResponse)req.GetResponse())
using (Stream rs = resp.GetResponseStream())
using (StreamReader sr = new StreamReader(rs)) {
string content = sr.ReadToEnd();
return content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
}
}
刪除與重命名
public void Delete(string fileName) {
var req = (FtpWebRequest)WebRequest.Create($"ftp://{FtpServerIP}/{fileName}");
req.Credentials = new NetworkCredential(FtpUser, FtpPass);
req.Method = WebRequestMethods.FTP.DeleteFile;
using (var resp = (FtpWebResponse)req.GetResponse()) { /* 檢查狀態 */ }
}
public void Rename(string oldName, string newName) {
var req = (FtpWebRequest)WebRequest.Create($"ftp://{FtpServerIP}/{oldName}");
req.Credentials = new NetworkCredential(FtpUser, FtpPass);
req.Method = WebRequestMethods.FTP.Rename;
req.RenameTo = newName; // 關鍵屬性
using (var resp = (FtpWebResponse)req.GetResponse()) { /* 檢查狀態 */ }
}
關鍵屬性與進階設定
| 屬性 | 用途 | 建議值 |
| UseBinary | 二進位/ASCII 模式 | true(除非純文字檔) |
| UsePassive | 被動模式 | true(穿透防火牆/NAT) |
| KeepAlive | 連線重用 | 單檔 false;批量 true |
| EnableSsl | FTPS 隱式/顯式 SSL | 伺服器支援時 true |
| Proxy | 代理伺服器 | 企業環境需設定 |
| Timeout / ReadWriteTimeout | 逾時毫秒 | 大檔案調大(預設 100s/300s) |
安全性與最佳實踐
- 啟用 SSL:`req.EnableSsl = true`,否則帳密明文傳輸。需伺服器支援 FTPS(Explicit/Implicit)。
- 例外處理:捕獲 `WebException`,檢查 `Response` 為 `FtpWebResponse` 取得狀態碼(550 不存在、530 未登入、553 權限不足等)。
- 大檔案斷點續傳:`FtpWebRequest` 原生不支援。需自行實作 `REST` 指令(`req.Method = "REST "`)或改用 FluentFTP 庫。
- 效能調優:批量操作時保持 `KeepAlive=true` 重用連線;緩衝區 8KB-64KB;平行上傳多檔案可用 `Parallel.ForEach` + 連線池。
現代替代庫推薦
- FluentFTP:功能最完整、支援非同步/續傳/SSL/列表解析/事件進度,NuGet 熱門首選。
- SSH.NET:若需 SFTP(SSH File Transfer Protocol),而非 FTPS。
- System.Net.FtpClient (舊版):FluentFTP 前身,已停止維護。