利用indy的tidftp控件实现ftp协议_delphi教程

目前非常多应用都需要上传和下载大型文件,通过HTTP方式上传大文件有一定的局限性。幸好FTP作为一个非常老而且非常成熟的协议能高效稳定地完成大文件的上传下载,并且能完美地实现续传。就拿我写的电影服务器管理端程式来说,各种方案比较后,发现使用FTP能完美地实现需求。不过要通过WinSocket库实现FTP比较麻烦,幸好有Indy--一个包装了大多数网络协议的组件包。 通过Indy,程式设计人员能通过阻塞方式进行编程,能抛开蹩脚的Winsocket异步模式,采用和Unix系统上等同的阻塞编程模式进行。这样,程式员就能非常好的处理程式的运行流程。 下面,我们进入到Indy的TIdFtp世界。 1.控件的说明 使用Indy 9中的TIdFtp控件能实现通过FTP方式进行文件的上传和下载。 2.控件的具体使用(1)控件属性设置 默认属性即可,和服务器连接直接相关的属性如主机名和用户等在建立连接时进行设定。需要设定的是RecvBufferSize和SendBufferSize 两属性的值。另外需要根据要传输的文件类型指定TransferType属性,而其他属性按默认值设定即可。 RecvBufferSize说明(默认值为8192字节):该属性为整型变量,用于指定连接所用的接受缓冲区大小。 SendBufferSize说明(默认值为32768字节):该属性也为整型变量,用于指定连接所用的发送缓冲区的最大值。该属性在WriteStream方 法中时,可用于TStream指定要发送内容的块数。如果要发送的内容大于本属性值,则发送内容被分为多个块发送。 TransferType说明(默认值为ftBinary):该属性为TIdFTPTransferType型变量。用于指定传输内容是二进制文件(ftBinary )还是 ASCII文件(ftASCII)。应用程式需要使用二进制方式传输可执行文件、压缩文件和多媒体文件等;而使用ASCII方式传输文本或超文本等 文本型数据。(2)控件的事件响应 OnDisconnected响应:TNotifyEvent类,用于响应断开(disconnect)事件。当Disconnect方法被调用用来关闭Socket的时候,触发该响 应。应用程式必须指定该事件响应的过程,以便对该断开事件进行相应。 OnStatus响应:TIdStatusEvent类。该响应在当前连接的状态变化时被触发。该事件可由DoStatus方法触发并提供给事件控制器属性。 axStatus是当前连接的TIdStatus值;aaArgs是个可选的参数用于格式化函数,他将用于构造表现当前连接状态的文本消息。 OnWork响应:OnWord是TWorkEvent类事件的响应控制器。OnWork用于关联DoWork方法当缓冲区读写操作被调用时通知Indy组件和类。他一 般被用于控制进度条和视窗元素的更新。AWorkMode表示当前操作的模式,其中:wmRead-组件正在读取数据;wmWrite-组件正在发送数据 。AWorkCount指示当前操作的字节计数。 OnWorkBegin响应:TWorkBeginEvent类。当缓冲区读写操作初始化时,该事件关联BeginWork方法用于通知Indy组件和类。他一般被用于控 制进度条和视窗元素的更新。AWorkMode表示当前操作的模式,其中:wmRead-组件正在读取数据;wmWrite-组件正在发送数据。 AWorkCountMax用于指示发送到OnWorkBegin事件的操作的最大字节数,0值代表未知。 OnWorkEnd响应:TWorkEndEvent类。当缓冲区读写操作终止时,该事件关联EndWork方法用于通知Indy组件和类。AWorkMode表示当前操作 的模式,其中:wmRead-组件正在读取数据;wmWrite-组件正在发送数据。AWorkCount表示操作的字节数。在事件响应中,主要通过上述五种事件响应来控制程式。在一般情况下,在OnDisconnected中设定连接断开的界面通知;在OnStatus中设定当前操作的状态;在OnWork中实现传输中状态条和其他参数的显示;而在OnWorkBegin和OnWorkEnd中分别设定开始传输和传输结束时的界面。(3)连接远程服务器 完成了设定控件属性和实现了控件的事件响应后,就能和服务器进行交互和传输了。在连接之前,应首先判断IdFtp是否处于连接状态,如果Connected为False,则通过界面控件或其他方式指定和服务器连接相关的一些TCP类属性的设置,分别是:Host(主机名):String、Username(用户名):String、Password(密码):String,也能指定Port(端口)。之后调用Connect方法连接远程服务器,如果无异常出现则连接成功建立。过程说明:procedure Connect(AAutoLogin: boolean; const ATimeout: Integer); 该过程连接远程FTP服务器属性:AAutoLogin: boolean = True 连接后自动登录,该参数默认为True。 const ATimeout: Integer = IdTimeoutDefault 超时时间,单位:秒。示例代码: if IdFTP1.Connected then try if TransferrignData then IdFTP1.Abort; IdFTP1.Quit; finally end else with IdFTP1 do try Username := UserIDEdit.Text; Password := PasswordEdit.Text; Host := FtpServerEdit.Text; Connect; ChangeDir(CurrentDirEdit.Text); finally end; (4)改动目录 连接建立后,能改动当前FTP会话所在的目录。对于已知绝对路径的情况下,能直接调用ChangeDir(const ADirName: string)方法来转换目录,ADirName表示服务器上的文件系统目录,另外还能调用ChangeDirUp回到上级目录。 如果未知路径,则能通过List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean)过程获取远程服务器的当前目录结构,此时必须设定TransferType为ftASCII(ASCII模式),其中:ADest保存当前目录结构,能在后续程式中调用该列表。另外能通过RetrieveCurrentDir方法获取当前目录名。过程说明: procedure ChangeDir(const ADirName: string); 改动工作目录属性 const ADirName: string 远程服务器的目录描述说明:该过程实际上是实现了FTP CWD命令。 procedure ChangeDirUp; 到上一级目录 function RetrieveCurrentDir: string; 该函数返回当前目录名 procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean); 列出当前目录所有文件和子目录及其属性参数: ADest: TStrings 保存文件及子目录的返回结果 const ASpecifier: string = 文件掩码,用于列出符合条件的文件 const ADetails: boolean = true 包含文件和子目录属性 property DirectoryListing: TIdFTPListItems; 返回文件及目录结构的列表 示例代码: LS := TStringList.Create; try IdFTP1.ChangeDir(DirName); IdFTP1.TransferType := ftASCII; CurrentDirEdit.Text := IdFTP1.RetrieveCurrentDir; DirectoryListBox.Items.Clear; IdFTP1.List(LS); DirectoryListBox.Items.Assign(LS); if DirectoryListBox.Items.Count > 0 then if AnsiPos(total, DirectoryListBox.Items[0]) > 0 then DirectoryListBox.Items.Delete(0); finally LS.Free; end; (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; 通过上述介绍,能在较短的时间内设计出稳定而功能强大的FTP客户端。上述代码大部分摘自Indy的Demo,读者能自己加入多线程的实现。在我的设计中,利用该控件上传大型影音文件,不仅支持文件续传,还能非常容易的实现多线程操作和意外处理。

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值