Delphi IdFTP[2] 常用过程、事件、方法介绍
Delphi IdFTP[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、过程、方法(Connext、ChangeDir、List、Get、Put)
3.1 连接
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;
3.2 改变目录
procedure ChangeDir(const ADirName: string); //改变工作目录
属性
- const ADirName: string //远程服务器的目录描述 说明:该过程实际上是实现了FTP CWD命令。
procedure ChangeDirUp; //到上一级目录 也可以用 ,IdFTP1.ChangeDir('..'); //返回上一级目录
function RetrieveCurrentDir: string; //该函数返回当前目录名
3.3 列表(目录、文件、属性)
procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean); //列出当前目录所有文件和子目录及其属性
参数:
- ADest: TStrings //保存文件及子目录的返回结果
- const ASpecifier: string = //文件掩码,用于列出符合条件的文件
- const ADetails: boolean = true //包含文件和子目录属性 true,返回所有属性(大小、时间、类型等),false 只显示名称
相对属性:
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;
也可以这样用(补充 2020.06.16):
IdFTP1.List(nil); //获取当前目录的所有信息 //或者 IdFTP1.List(DirList); //这个会得到列表的所有信息,包含时间、大小、类型等,相当于 IdFTP1.List(DirList,'',true); //或者 IdFTP1.List(DirList,'',False); //得到FTP路径下的所有文件夹名称 给到 DirList ,false只获取目录名称 ,这种方式获取的数据不包含数据类型的判断 //或者 IdFTP1.List; //支持Delphi XE 版本 //或者 IdFTP1.List('',False); //支持Delphi XE 版本 //看源代码: procedure TIdFTP.List; begin List(nil); end; procedure TIdFTP.List(const ASpecifier: string; ADetails: Boolean); begin List(nil, ASpecifier, ADetails); end; procedure TIdFTP.List(ADest: TStrings; const ASpecifier: string = ''; ADetails: Boolean = True); {do not localize} var LDest: TMemoryStream; LTrans : TIdFTPTransferType; begin if ADetails and UseMLIS and FCanUseMLS then begin ExtListDir(ADest, ASpecifier); Exit; end; // Note that for LIST, it might be best to put the connection in ASCII mode. because some old servers such as TOPS20 might require this. We restore it if the original mode was not ASCII. // It's a good idea to do this anyway because some clients still do this such as WS_FTP Pro and Microsoft's FTP Client. {注意,对于LIST,最好将连接设置为ASCII模式。因为像top20这样的旧服务器可能需要这个。如果原始模式不是ASCII,我们将恢复它。无论如何,这样做是一个好的方式,因为有些客户机仍然这样做,如WS_FTP Pro和微软的FTP客户机。} LTrans := TransferType; if LTrans <> ftASCII then begin Self.TransferType := ftASCII; end; try LDest := TMemoryStream.Create; try InternalGet(Trim(iif(ADetails, 'LIST', 'NLST') + ' ' + ASpecifier), LDest); {do not localize} FreeAndNil(FDirectoryListing); FDirFormat := ''; LDest.Position := 0; FListResult.Text := ReadStringFromStream(LDest, -1, IOHandler.DefStringEncoding{$IFDEF STRING_IS_ANSI}, IOHandler.DefAnsiEncoding{$ENDIF}); TIdFTPListResult(FListResult).FDetails := ADetails; TIdFTPListResult(FListResult).FUsedMLS := False; // FDirFormat will be updated in ParseFTPList... finally FreeAndNil(LDest); end; if ADest <> nil then begin ADest.Assign(FListResult); end; DoOnRetrievedDir; finally if LTrans <> ftASCII then begin TransferType := LTrans; end; end; end;
3.4 下载
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 //远程服务器上的源文件名,即FTP服务器上的文件名。
- ADest:TStream //将写入文件数据的流。
- const ADestFile: string //保存到客户机上的文件名 (本地计算机上的文件名和可选路径)
- const ACanOverwrite: boolean = false //重写同名文件 (用相同的名称覆盖现有文件)
- AResume: Boolean = false //是否进行断点续传 (可以完成部分下载)
示例代码:(优化2022.08)
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; end;
提示:下载之前,查看 DirectoryListing.Items[sCurrFile].ItemType是否为文件,如返回为ditDirectory则代表当前文件名为目录,不能下载,必须导向到文件才可。如为文件,则可以进行下载。在下载前,设定传输的类型为二进制文件,并且指定本地要保存的路径。通过调用Get方法,实现文件的下载。下载过程较慢,可以考虑将其放到线程中实现。
其他描述:Get是一个重载过程,允许FTP客户端使用FTP RETR命令谓词从FTP服务器检索具有ASourceFile中指定名称的文件。Get的重载实现为来自FTP服务器的数据使用基于文件或流的目的地,如ADestFile或ADest中指定的。
当AResume为True且CanResume指示FTP服务器实现允许FTP REST命令谓词时,Get允许继续先前的部分下载或将数据附加到本地文件系统上的现有文件。
在基于文件的方法变体中,当ACanOverwrite为True或文件不存在时,将在检索数据之前创建目标文件。当ACanOverwite为False且AResume为True时,将打开目标文件并将其定位到文件末尾,然后再检索数据。
当ADestFile中的目标文件已经存在,并且ACanOverwrite和AResume都包含False时,将引发EidftpFileReadyExists异常。
在Get方法的基于流的变体中,可以在ADest中指定的流中访问从FTP服务器返回的数据。在数据检索期间,Get调用一些方法,这些方法使用被动中指定的连接类型初始化FTP客户端的数据通道。这些受保护的方法还使用ftpTransfer状态值触发OnStatus事件处理程序,从FTP服务器读取流数据,并在完成时使用ftpReady状态值向OnStatus事务处理程序发送信号。如果来自FTP服务器的响应代码是数值225,则可以使用值ftpAborted触发OnStatus matus。
检索过程完成后,Get使用ADest中指定的流作为参数向OnAfterGet事件处理程序发送信号。
3.5 上传
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;
3.6 删除文件/文件夹
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;
创建时间:2020.05.11 更新时间:2020.06.16、2022.08.05、08.09