HTTP 上傳大型檔案受限於逾時與記憶體,FTP 協定成熟穩定且原生支援斷點續傳,是大檔案傳輸的首選。Indy 元件庫封裝了阻塞式 Socket 操作,讓開發者脫離複雜的非同步模型,以循序漸進的同步邏輯撰寫 FTP 用戶端。本文系統整理 TIdFTP 核心屬性、事件、常用方法與實戰範例,並探討多執行緒架構避免介面凍結。
| 屬性 | 預設值 | 說明 |
|---|---|---|
RecvBufferSize | 8192 | 接收緩衝區大小(位元組) |
SendBufferSize | 32768 | 發送緩衝區大小,WriteStream 時決定分塊大小 |
TransferType | ftBinary | ftBinary:二進制(執行檔、壓縮檔、多媒體);ftASCII:文字檔 |
五大事件構成傳輸監控骨幹:
OnDisconnected:連線中斷通知OnStatus:狀態文字變更(連線中、登入中、傳輸中...)OnWorkBegin:傳輸啟動,取得 AWorkCountMax 設定進度條 MaxOnWork:傳輸中,依 AWorkCount 更新進度條 PositionOnWorkEnd:傳輸結束,重設介面狀態if not IdFTP1.Connected then begin
IdFTP1.Host := FtpServerEdit.Text;
IdFTP1.Username := UserIDEdit.Text;
IdFTP1.Password := PasswordEdit.Text;
IdFTP1.Connect;
IdFTP1.ChangeDir(CurrentDirEdit.Text); // 切換工作目錄
end;
目錄列舉需設定 TransferType := ftASCII,呼叫 List(LS) 取得字串清單,或使用 DirectoryListing 屬性取得結構化 TIdFTPListItems。
IdFTP1.TransferType := ftBinary;
RemoteSize := IdFTP1.Size(RemoteFileName);
if FileExists(LocalFileName) then begin
LocalSize := FileSizeByName(LocalFileName);
if MessageDlg('檔案已存在,是否續傳?', mtConfirmation, [mbYes, mbNo, mbCancel], 0) = mrYes then
IdFTP1.Get(RemoteFileName, LocalFileName, False, True) // AResume = True
else
IdFTP1.Get(RemoteFileName, LocalFileName, True); // 覆寫
end else
IdFTP1.Get(RemoteFileName, LocalFileName, False);
Get 多載支援 TStream 或檔案路徑,AResume 參數啟用續傳。
IdFTP1.TransferType := ftBinary;
IdFTP1.Put(LocalFileName, RemoteFileName, True); // AAppend = True 續傳
// 刪除檔案
IdFTP1.Delete(FileName);
// 刪除目錄(需先清空)
IdFTP1.RemoveDir(DirName);
// 返回上層
IdFTP1.ChangeDirUp;
// 取消目前傳輸
IdFTP1.Abort;
Indy 為阻塞模式,傳輸期間主執行緒會卡住。解決方案:
TIdThreadComponent 將 FTP 操作封裝於背景執行緒CreateThread,透過 Synchronize / Queue 更新 UIAbortTransfer := True,在 OnWork 中檢查並呼叫 IdFTP1.AbortTIdFTP + TIdThreadComponent 放於資料模組Indy 官方文件與原始碼可參考 indyproject.org。掌握 TIdFTP 事件流與續傳邏輯,即可打造穩健的大檔案傳輸模組。