各位老大,做ftp客户端程序,如何遍历ftp服务器上某一个目录下所有的文件?
在线等待,解决马上给分,决不失言!!!!

解决方案 »

  1.   

    请注意:
    不需要使用ListBox控件的辅助得到ftp服务器上的目录和文件名
      

  2.   

    使用WININET API函数吧
    用FTPFINDFIRSTFILE找到第一个文件,然后使用INTERNETNEXTFILE查找下一个文件即可,如果还要对子目录进行遍历,则递归调用就可以了。
      

  3.   

    上面的查找下一个文件的API函数敲错了,应该是InternetFindNextFile函数,
      

  4.   

    很麻烦的
    递归列表所有文件
    如果服务器支持List的-al参数就简单了,直接在结果分析即可
      

  5.   

    我也想知道,不知道InternetFindNextFile该怎样使用,我已经得到了一个目录下的所有文件名称,但不知道该怎样区分文件名和文件夹
      

  6.   

    function GetFTPDirectory(hConnect: Pointer): String ;
    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;