首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 整合 Indy TIdFTP 實現 FTP 上傳下載與斷點續傳完整指南

     編輯:ASP.NET 基礎

為什麼選擇 FTP 與 Indy 元件?

HTTP 上傳大檔案受限於 IIS 上傳大小限制、逾時設定、無法斷點續傳 等缺陷。FTP 協定成熟穩定,原生支援大檔傳輸與續傳。Indy (Internet Direct) 封裝了阻塞式 Socket 操作,讓開發者以同步程式碼風格處理網路傳輸,避開非同步回呼地獄,是 WinForms/WPF/ASP.NET 伺服端整合 FTP 的首選庫。

核心功能速覽表

功能關鍵方法/屬性說明
連線Connect(), Host, Username, Password, Port支援自動登入與逾時設定
目錄操作ChangeDir(), ChangeDirUp(), List(), RetrieveCurrentDir()切換、列舉、取得當前路徑
下載Get(remote, local, overwrite, resume)支援串流/檔案、覆寫、斷點續傳
上傳Put(local, remote, append)支援串流/檔案、續傳模式
刪除Delete(file), RemoveDir(dir)檔案/目錄刪除(目錄需為空)
進度監控OnWorkBegin, OnWork, OnWorkEnd即時更新進度條、速度、剩餘時間
狀態通知OnStatus, OnDisconnected連線狀態變化、斷線偵測

關鍵屬性深度設定

傳輸緩衝區優化

IdFTP1.RecvBufferSize = 8192;   // 接收緩衝 8KB(預設)
IdFTP1.SendBufferSize = 32768;  // 發送緩衝 32KB(預設)

大檔傳輸可適度調大 SendBufferSize(如 64KB-256KB),減少系統呼叫次數,提升吞吐量。

傳輸模式:二進位 vs ASCII

IdFTP1.TransferType = TIdFTPTransferType.ftBinary;  // 二進位:圖片、壓縮檔、執行檔、Word/Excel
IdFTP1.TransferType = TIdFTPTransferType.ftASCII;   // ASCII:純文字、HTML、XML、原始碼

鐵律:List() 目錄列舉必須用 ftASCII,檔案上傳下載必須用 ftBinary,錯誤模式會導致二進位檔損毀或文字換行符錯誤。

完整連線與操作流程範例

1. 連線與登入

if (!IdFTP1.Connected) {
    IdFTP1.Host = "ftp.example.com";
    IdFTP1.Username = "user";
    IdFTP1.Password = "pass";
    IdFTP1.Port = 21;
    IdFTP1.Connect(); // 預設 AAutoLogin=true, ATimeout=無限
    
    // 進入目標目錄
    IdFTP1.ChangeDir("/upload/images");
}

2. 列舉遠端目錄(取得檔案清單)

IdFTP1.TransferType = TIdFTPTransferType.ftASCII; // 必須!
var listing = new StringList();
IdFTP1.List(listing); // 同步阻塞直到完成

foreach (var item in listing) {
    Console.WriteLine($"{item.FileName} | {item.Size} | {item.ModifiedDate} | {(item.ItemType == TIdDirItemType.ditDirectory ? "DIR" : "FILE")}");
}

3. 下載檔案(含斷點續傳邏輯)

IdFTP1.TransferType = TIdFTPTransferType.ftBinary;
string remoteFile = "large_video.mp4";
string localFile = @"C:\Downloads\large_video.mp4";
long remoteSize = IdFTP1.Size(remoteFile); // 取得遠端檔案大小

bool resume = File.Exists(localFile);
long localSize = resume ? new FileInfo(localFile).Length : 0;

if (resume && localSize < remoteSize) {
    // 續傳模式:append=true, resume=true
    IdFTP1.Get(remoteFile, localFile, false, true); 
} else if (!resume) {
    // 全新下載
    IdFTP1.Get(remoteFile, localFile, true, false);
} else {
    Console.WriteLine("檔案已完整存在");
}

4. 上傳檔案(含續傳)

IdFTP1.TransferType = TIdFTPTransferType.ftBinary;
string localFile = @"C:\Data\backup.zip";
string remoteFile = "backup.zip";

bool resume = false; // 檢查遠端是否有部分檔案邏輯...
IdFTP1.Put(localFile, remoteFile, resume); // append=resume

進階議題:多執行緒與 UI 回應性

Indy 為阻塞式設計,Get/Put 會凍結呼叫執行緒。在 WinForms/WPF/ASP.NET 中必須放入背景執行緒:

// WinForms 範例:BackgroundWorker 或 Task.Run
Task.Run(() => {
    try {
        IdFTP1.Get(remote, local, false, true);
        // 完成後用 Invoke/BeginInvoke 更新 UI
        this.BeginInvoke((Action)(() => lblStatus.Text = "下載完成"));
    } catch (Exception ex) {
        this.BeginInvoke((Action)(() => MessageBox.Show(ex.Message)));
    }
});

Indy 也提供 TIdThreadComponent 簡化執行緒管理,但現代 .NET 建議直接使用 Task/async-await 包裝阻塞呼叫。

斷點續傳核心原理

  1. 下載續傳:比較本地檔案大小與遠端 Size(),若本地較小 → Get(..., resume: true),FTP 指令 REST 設定續傳位移
  2. 上傳續傳:Put(..., append: true),FTP 指令 APPE 從檔案尾部續寫
  3. 前提條件:FTP 伺服器必須支援 REST (下載) 與 APPE (上傳) 指令,多數現代 FTP Server (vsftpd, ProFTPD, FileZilla Server, IIS FTP) 均支援

常見錯誤與排除

現象可能原因解決方案
連線逾時防火牆阻擋、Port 錯誤、被動模式問題設定 Passive=true、開啟防火牆 21 + 被動埠範圍
中文檔名亂碼FTP 伺服器編碼不一致設定 IdFTP1.Encoding = Encoding.GetEncoding("utf-8") (Indy 10.6+)
大檔傳輸中斷逾時設定過短、網路不穩調大 ReadTimeout/WriteTimeout、啟用續傳邏輯
List() 回傳空白TransferType 錯誤列目錄前強制 ftASCII
權限拒絕 550帳號無寫入/刪除權限檢查 FTP 使用者權限、目錄 ACL

總結

Indy TIdFTP 提供功能完整、API 直覺的 FTP 客戶端實作。掌握 連線管理、傳輸模式切換、續傳邏輯、多執行緒整合 四大核心,即能建構穩健的大檔案傳輸系統。現代專案建議搭配 Task.Run 非同步化阻塞呼叫,並妥善處理編碼、逾時、防火牆等環境變數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved