各位老大,做ftp客户端程序,如何遍历ftp服务器上某一个目录下所有的文件?
在线等待,解决马上给分,决不失言!!!!
在线等待,解决马上给分,决不失言!!!!
解决方案 »
- ★★★★★我也送阿日★★★★★
- 安装新组件中出现的一些新问题
- 关于窗口重画的问题,求助
- stack overflow 的错误
- 如何制作自己的vcl控件?
- 寻求用DELPHI开发中的支持插件的技术,相关资料和例子。学习。
- 请问DrawText API函数能否使一个长单词在一个宽度不足以容纳此单词的矩形中折行,使得长单词显示完整?
- 关于delphi与directsound的问题...
- 我想在屏幕显示一个字符之前,先用程序将之截获,判断如果不是想显示的字母,则不让Tedit显示它!
- 怎样避免出现Asynchronous socket error 10054/Asynchronous socket error 10053的错误
- 用SetwindowPos将一个窗口HWND_TOPMOST之后怎么变成正常(不是最前的)的窗口啊?
- 初学者求助!各位帮帮忙!
不需要使用ListBox控件的辅助得到ftp服务器上的目录和文件名
用FTPFINDFIRSTFILE找到第一个文件,然后使用INTERNETNEXTFILE查找下一个文件即可,如果还要对子目录进行遍历,则递归调用就可以了。
递归列表所有文件
如果服务器支持List的-al参数就简单了,直接在结果分析即可
var
dwDir : DWORD;
Dir : array [0..255] of Char;
begin
if ( hConnect = nil ) then begin
Result :='';
Exit;
end;
dwDir := SizeOf( Dir ); // FtpGetCurrentDirectory retrieves the current directory for the connection.
// returns True if successful
if FtpGetCurrentDirectory( hConnect, Dir, dwDir ) Then
begin
if StrRScan(Dir, '/') + 1 = StrEnd(Dir) then
Result := Trim( StrPas(Dir) )
else Result := Trim( StrPas(Dir) ) + '/';
end;
end;function GetFTPDirectoryContents( hConnect: Pointer ): TStringList;
var
WFD : TWin32FindData;
hFind : Pointer;
FTPPath : String;
lst : TStringList;
begin
if ( hConnect = nil ) then begin
Result :=nil;
Exit;
end;
lst :=TStringList.Create; // Obtain the current FTP path
FTPPath := GetFTPDirectory( hConnect );
FTPPath := FTPPath + '*.*' ; // obtain the file handles via FtpFindFirstFile
// Search the first available file or directory
hFind :=FtpFindFirstFile( hConnect,
PChar(FTPPath),
WFD,
INTERNET_FLAG_RELOAD OR INTERNET_FLAG_NO_CACHE_WRITE,
$0
); If ( hFind = nil ) then begin
Result :=nil;
Exit;
end; repeat
If StrLen( WFD.cFileName ) > 0 then
begin
If WFD.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY then
lst.Add( StrPas(WFD.cFileName) + '/' )
else lst.Add( StrPas(WFD.cFileName) );
end ; // Search the next available file or directory
until not InternetFindNextFile( hFind, @WFD ); // Close file handle
InternetCloseHandle( hFind );
Result :=lst;
end;存API写的,不太好用,明白方法就可以了:
procedure TfrmMain.btnConnectClick(Sender: TObject);
label
CreateSession,
ConnectFtpHost,
GetCurrentDir,
GetList;
var
s : String;
lst : TStrings;
i : Integer;
AItem : TListItem;
begin
ftpHost :=Trim( edtHost.Text );
ftpPort :=21;
ftpTimeOut :=30000;
ftpUser :=Trim( edtUser.Text );
ftpPwd :=Trim( edtPwd.Text );
ftpUseProxy :=false; StopConnect :=false; CreateSession:
lsbLog.Lines.Add( 'STATUS :> Connecting to ' +ftpHost ); if ftpUseProxy then
hInternet :=InternetOpen( PChar('FTP Application'),
INTERNET_OPEN_TYPE_PROXY,
nil,
nil,
INTERNET_FLAG_NO_CACHE_WRITE
)
else
hInternet :=InternetOpen( PChar('FTP Application'),
INTERNET_OPEN_TYPE_DIRECT,
nil,
nil,
INTERNET_FLAG_NO_CACHE_WRITE
); // If not internet session created OK
if ( hInternet = nil ) then
begin
lsbLog.Lines.Add( 'ERROR :> Internet Connection Session can not be created.' );
lsbLog.Lines.Add( 'STATUS :> Waiting for try again...' );
Application.ProcessMessages;
if not StopConnect then
begin
if lsbLog.Lines.Count > 99 then lsbLog.Lines.Clear;
goto CreateSession;
end
else begin
lsbLog.Lines.Add( 'STATUS :> Disconnecting...' );
Exit;
end;
end; ConnectFtpHost:
if ( ftpUser = '' ) and ( ftpPwd = '') then
// anonymous
hConnect := InternetConnect( hInternet, PChar( ftpHost ),
INTERNET_DEFAULT_FTP_PORT,
nil,
nil,
INTERNET_SERVICE_FTP,
INTERNET_FLAG_EXISTING_CONNECT OR INTERNET_FLAG_PASSIVE,
$0
)
else
hConnect := InternetConnect( hInternet, PChar( ftpHost ),
INTERNET_DEFAULT_FTP_PORT,
PChar( ftpUser ),
PChar( ftpPwd ),
INTERNET_SERVICE_FTP,
INTERNET_FLAG_EXISTING_CONNECT OR INTERNET_FLAG_PASSIVE,
$0
); // If not connection created OK
If ( hConnect = nil ) Then
begin
lsbLog.Lines.Add( 'ERROR :> Can not resolve host name.' );
lsbLog.Lines.Add( 'ERROR :> Can not login. Still trying...' );
lsbLog.Lines.Add( 'STATUS :> Waiting for try again...' );
Application.ProcessMessages;
if not StopConnect then
begin
if lsbLog.Lines.Count > 99 then lsbLog.Lines.Clear;
goto ConnectFtpHost;
end
else begin
lsbLog.Lines.Add( 'STATUS :> Disconnecting...' );
Exit;
end;
end;
lsbLog.Lines.Add( 'STATUS: > OK, Login succeed.' ); GetCurrentDir:
lsbLog.Lines.Add( 'STATUS: > Get current directory...' ); s :=GetFTPDirectory( hConnect );
if s ='' then
begin
lsbLog.Lines.Add( 'ERROR :> Get current directory failed.' );
lsbLog.Lines.Add( 'STATUS :> Waiting for try again...' );
Application.ProcessMessages;
if not StopConnect then
begin
if lsbLog.Lines.Count > 99 then lsbLog.Lines.Clear;
goto GetCurrentDir;
end
else begin
lsbLog.Lines.Add( 'STATUS :> Disconnecting...' );
Exit;
end;
end; lsbLog.Lines.Add( 'STATUS :> Get current directory succeed.' );
lsbLog.Lines.Add( 'STATUS :> Current directory is : ' + s );
ComboFTP.Items.Add( s );
ComboFTP.Text :=s; GetList:
lsbLog.Lines.Add( 'STATUS :> Command : Dir...' ); lst :=TStringList.Create;
lst.Clear;
lst :=GetFTPDirectoryContents( hConnect );
if lst = nil then
begin
lsbLog.Lines.Add( 'ERROR :> Command : Dir failed.' );
lsbLog.Lines.Add( 'STATUS :> Waiting for try again...' );
Application.ProcessMessages;
if not StopConnect then
begin
if lsbLog.Lines.Count > 99 then lsbLog.Lines.Clear;
goto GetList;
end
else begin
lsbLog.Lines.Add( 'STATUS :> Disconnecting...' );
Exit;
end;
end; lsbLog.Lines.Add( 'STATUS :> Command : Dir succeed.' );
for i :=0 to lst.Count -1 do
begin
s :=lst.Strings[i];
if s[ length(s) ]= '/' then
begin
s :=Copy( s, 1, Length(s) -1 );
AItem :=lsbFTP.Items.Add;
AItem.Data :=dtDirectory;
AItem.ImageIndex :=0;
end
else begin
AItem :=lsbFTP.Items.Add;
AItem.Data :=dtFile;
AItem.ImageIndex :=1;
end;
AItem.Caption := s;
end; lst.Free;