科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件利用Indy的TIdFtp控件实现FTP协议

利用Indy的TIdFtp控件实现FTP协议

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

现在很多应用都需要上传与下载大型文件,通过HTTP方式上传大文件有一定的局限性。

作者:cokeyang 来源:csdn 2007年10月31日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
(5)实现下载

  在下载之前,必须查看DirectoryListing.Items[sCurrFile].ItemType是否为文件,如返回为ditDirectory则代表当前文件名为目录,不能下载,必须导向到文件才可。如为文件,则可以进行下载。在下载前,设定传输的类型为二进制文件,并且指定本地要保存的路径。通过调用Get方法,实现文件的下载。下载过程较慢,可以考虑将其放到线程中实现。

  过程说明:

procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;

procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;

  从远程服务器上获取文件。

  属性说明:

const ASourceFile: string

  远程服务器上的源文件名

const ADestFile: string

  保存到客户机上的文件名

const ACanOverwrite: boolean = false

  重写同名文件

AResume: Boolean = false

  是否进行断点续传

  示例代码:

SaveDialog1.FileName := Name;

if SaveDialog1.Execute then begin

SetFunctionButtons(false);

IdFTP1.TransferType := ftBinary;

BytesToTransfer := IdFTP1.Size(Name);



if FileExists(Name) then begin

case MessageDlg('File aready exists. Do you want to resume the download operation?',

mtConfirmation, mbYesNoCancel, 0) of

mrYes: begin

BytesToTransfer := BytesToTransfer - FileSizeByName(Name);

IdFTP1.Get(Name, SaveDialog1.FileName, false, true);

end;

mrNo: begin

IdFTP1.Get(Name, SaveDialog1.FileName, true);

end;

mrCancel: begin

exit;

end;

end;

end

else begin

IdFTP1.Get(Name, SaveDialog1.FileName, false);

end;

  (6)上传的实现

  上传的实现与下载类似,通过put方法即可。

  过程说明:

procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;

procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;

  上传文件至服务器

  属性说明:

const ASourceFile: string

  将要被上传的文件

const ADestFile: string = ''

  服务器上的目标文件名

const AAppend: boolean = false

  是否继续上传

  代码示例:

if IdFTP1.Connected then begin

if UploadOpenDialog1.Execute then try

IdFTP1.TransferType := ftBinary;

IdFTP1.Put(UploadOpenDialog1.FileName, ExtractFileName(UploadOpenDialog1.FileName));

//可以在此添加改变目录的代码;

finally

//完成清除工作

end;

end;

  (7)删除的实现

  删除文件使用Delete方法,该方法删除指定的文件,删除对象必须为文件。如果要删除目录则使用RemoveDir方法。

  过程说明:

procedure Delete(const AFilename: string);

  删除文件

procedure RemoveDir(const ADirName: string);

  删除文件夹,根据不同的服务器删除文件夹有不同的要求。有些服务器不允许删除非空文件夹,程序员需要添加清空目录的代码。

  上述两个过程的参数均为目标名称

  代码示例:

if not IdFTP1.Connected then exit;

Name := IdFTP1.DirectoryListing.Items[iCurrSelect].FileName;

if IdFTP1.DirectoryListing.Items[iCurrSelect].ItemType = ditDirectory then try

idftp1.RemoveDir(Name);

finally

end

else

try

idftp1.Delete(Name);

finally

end;

  (8)后退的实现

  后退在实际上是目录操作的一种,可以简单的改变当前目录为..来实现,也可以通过回到上级目录来实现。

  (9)取消的实现

  在IdFtp的传输过程中,可以随时使用abort方法取消当前操作。可以的OnWork事件的实现中来确定何时取消操作。

  代码示例:

//取消按钮的OnClick响应

procedure TMainForm.AbortButtonClick(Sender: TObject);

begin

AbortTransfer := true;

end;

//IdFTP的OnWork事件响应

procedure TMainForm.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;

const AWorkCount: Integer);

begin

...

if AbortTransfer then IdFTP1.Abort;

AbortTransfer := false;

end;

  (10)断点续传的实现

  断点续传就是在上传或下载过程开始时,判断已经传输过的文件是否上传输完毕,如果传输没有成功完成,则在上次中断处继续进行传输工作。实现该功能需要两个重要的操作,首先是判断文件的大小信息,其次是在传输过程Get和Put中指定上传的行为。

  判断服务器上文件的大小使用函数Size(FileName)。在下载过程中,比较本地文件和远程文件的信息,然后在Get中指定AResume := True即可。而上传也一样,指定Put的AAppend := True就可以了。

  在前面我们讲过,Indy的网络操作大部分是阻塞模式的,TIdFtp也不例外。这样在上述各个操作运行过程的时候用户界面被暂时冻结,必须要等待调用返回才能继续用户操作界面响应。所以在实际编程中,需要使用多线程的方式来保证户界面的响应。Windows系统可以使用CreateThread系统调用来创建线程,但是在使用的时候需要开发人员做很多额外的工作来保证线程的同步等问题。而Indy中也包含了实现多线程的控件TIdThreadComponent,相对比之下该控件实现多线程时更加方便,也更容易控制。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章