| 屬性 | 用途 | 建議值 |
|---|---|---|
| Credentials | FTP 認證憑證 | new NetworkCredential(user, pass) |
| KeepAlive | 控制連線是否持久 | false(單次操作)、true(批量操作) |
| UseBinary | 傳輸模式:二進位/ASCII | true(二進位,通用安全) |
| UsePassive | 被動/主動模式 | true(被動,穿透防火牆) |
| ContentLength | 上傳檔案大小(通知伺服器) | fileInfo.Length |
| Method | FTP 指令 | WebRequestMethods.Ftp.UploadFile 等 |
| EnableSsl | 啟用 FTPS 加密 | true(若伺服器支援) |
主動模式 (PORT):伺服器從 Port 20 主動連線客戶端高位埠。客戶端防火牆常封鎖 → 失敗。
被動模式 (PASV):客戶端主動連線伺服器高位埠。伺服器通常開放範圍 → 成功率高。
結論:預設 UsePassive = true。
public void Upload(string localFilePath)
{
FileInfo fileInfo = new FileInfo(localFilePath);
string uri = $"ftp://{FtpServerIP}/{fileInfo.Name}";
var request = (FtpWebRequest)WebRequest.Create(uri);
request.Credentials = new NetworkCredential(FtpUserId, FtpPassword);
request.KeepAlive = false;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.ContentLength = fileInfo.Length;
const int BufferSize = 2048;
byte[] buffer = new byte[BufferSize];
using (var fileStream = fileInfo.OpenRead())
using (var requestStream = request.GetRequestStream())
{
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, BufferSize)) > 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
}
// 取得回應確認完成
using (var response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine($"上傳完成,狀態:{response.StatusDescription}");
}
}
request.Method = WebRequestMethods.Ftp.AppendFile;
// 需搭配 RestartOffset (需 .NET 4.5+ 或自行發送 REST 指令)
try
{
// FTP 操作
}
catch (WebException ex) when (ex.Response is FtpWebResponse ftpResp)
{
Console.WriteLine($"FTP 錯誤:{ftpResp.StatusCode} - {ftpResp.StatusDescription}");
}
catch (WebException ex)
{
Console.WriteLine($"網路錯誤:{ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"未預期錯誤:{ex.Message}");
}