导语: 如果ftp server支持REST指令(可以通过ftp client登入,然后输入REST 100,然后检查服务端响应),则上传或下载失败后,下次连接成功后可以从断点开始继续传输数据;
下面是基于Delphi7的组件IdFTP的示例代码,比自己用指令实现方便。
断点上传:
procedure TFtpThread.Execute; var AFileStream: TFileStream; sFileName: string; begin sFileName := ExtractFileName(AFileName); AFileStream := TFileStream.Create(AFileName, fmOpenRead); try with frmMain.IdFTP2 do try if Connected then Disconnect; //重新连接 Username := 'zzzz'; Password := 'yyyyyy'; Host := 'xx.xx.xx.xx'; Port := 21; Passive := mypassive; Connect; except on e: Exception do begin frmMain.StatusBar1.Panels[0].Text := '出错,异常:' + E.Message; frmMain.WriteLog(E.Message); AFileStream.Free; exit; end; end; // 获取断点 finishedSize := frmMain.IdFTP2.Size(sFileName); AFileStream.Seek(finishedSize, soFromBeginning); // 开始断点续传 BytesToTransfer := AFileStream.Size; frmMain.ProgressBar1.Max := BytesToTransfer div 1024; AFileStream.Position := finishedSize; try {while (not Terminated) and (AFileStream.Position < AFileStream.Size) do begin frmMain.IdFTP2.Put(AFileStream, sFileName, true); end; AMemStream.Free; } frmMain.IdFTP2.Put(AFileStream, sFileName, true); except on e: Exception do begin frmMain.StatusBar1.Panels[0].Text := '出错,异常:' + E.Message; frmMain.WriteLog(E.Message); AFileStream.Free; exit; end; end; // 判断是否上传完毕 if AFileStream.Position = AFileStream.Size then frmMain.StatusBar1.Panels[0].Text := '上传完毕!' else frmMain.StatusBar1.Panels[0].Text := '未完成上传,点击上传继续传输!'; AFileStream.Free; except on e: Exception do begin frmMain.StatusBar1.Panels[0].Text := '出错,异常:' + E.Message; frmMain.WriteLog(E.Message); AFileStream.Free; exit; end; end; end;
断点下载:
procedure TfrmMain.FtpDownLoad(aURL, aFile: string); var tStream: TFileStream; sName, sPass, sHost, sPort, sDir,sFile: string; bResume: Boolean; begin //ftp方式下载 if FileExists(aFile) then //建立文件流 tStream := TFileStream.Create(aFile, fmOpenWrite) else tStream := TFileStream.Create(aFile, fmCreate); GetFTPParams(aURL, sName, sPass, sHost, sPort, sDir,sFile); with IdFTP1 do try if Connected then Disconnect; //重新连接 Username := sName; Password := sPass; Host := sHost; Port := StrToInt(sPort); Passive := mypassive; Connect; except on e: Exception do begin Application.MessageBox(PChar(E.Message), 'error', 16); WriteLog(E.Message); exit; end; end; IdFTP1.ChangeDir(sDir); //改变目录 BytesToTransfer := IdFTP1.Size(sFile); ProgressBar1.Max := BytesToTransfer div 1024; if FileExists(aFile) then bResume := true else bResume := false; try if bResume then //续传 begin //ProgressBar1.Position := tStream.Size div 1024; finishedSize := tStream.Size; tStream.Position := tStream.Size; IdFTP1.Get(sFile, tStream, True); end else begin IdFTP1.Get(sFile, tStream, False); end; if tStream.Position = BytesToTransfer then begin StatusBar1.Panels[0].Text := '下载完成'; end; finally tStream.Free; end; end; //ftp://user:pwd@foolish.6600.org:2003/soft/list.mp4 procedure TfrmMain.GetFTPParams(var aURL, sName, sPass, sHost, sPort, sDir,sFile: String); var URI: TIdURI; begin URI := TIdURI.Create(aURL); //建立 try sHost := URI.Host; //主机 sPort := URI.Port; sName := URI.Username; sPass := URI.Password; sDir := URI.Path; sFile := URI.Document; finally URI.Free; end; end;