2010-04-05 2 views
7

Die listFiles() Methode von org.apache.commons.net.ftp.FTPClient mit Filezilla Server auf 127.0.0.1 funktioniert gut, aber kehrt null im Stammverzeichnis der öffentlichen FTP-Server wie belnet.be.Ausgabe mit org.apache.commons.net.ftp.FTPClient Listfiles()

Es gibt eine identische Frage auf den Link unten, aber enterRemotePassiveMode() scheint nicht zu helfen. Apache Commons FTPClient.listFiles

Könnte es ein Problem mit der Analyse von Listen sein? Wenn ja, wie kann das gelöst werden?

Edit: Hier ist ein Verzeichnis-Cache-Dump:

FileZilla Verzeichnis Cache Dump

Dumping 1 im Cache-Verzeichnisse

Entry 1: 
Path:/
Server: [email protected]:21, type: 4096 
Directory contains 7 items: 
    lrw-r--r-- ftp ftp  D   28  2009-06-17 debian 
    lrw-r--r-- ftp ftp  D   31  2009-06-17 debian-cd 
    -rw-r--r-- ftp ftp     0 2010-03-04 13:30 keepalive.txt 
    drwxr-xr-x ftp ftp  D  4096 2010-02-18 14:22 mirror 
    lrw-r--r-- ftp ftp  D   6  2009-06-17 mirrors 
    drwxr-xr-x ftp ftp  D  4096  2009-06-23 packages 
    lrw-r--r-- ftp ftp  D   1  2009-06-17 pub 

meinen Code Hier ist mit einem Wrapper ich gemacht habe (Prüfung innerhalb der Umhüllung erzeugt die gleichen Ergebnisse):

public static void main(String[] args) {   
    FTPUtils ftpUtils = new FTPUtils(); 
    String ftpURL = "ftp.belnet.be"; 
    Connection connection = ftpUtils.getFTPClientManager().getConnection(ftpURL); 

    if(connection == null){ 
     System.out.println("Could not connect"); 
     return; 
    } 

    FTPClientManager manager = connection.getFptClientManager(); 
    FTPClient client = manager.getClient(); 

    try { 
     client.enterRemotePassiveMode(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    if(connection != null){ 
     System.out.println("Connected to FTP"); 
     connection.login("Anonymous", "Anonymous"); 
     if(connection.isLoggedIn()){ 
      System.out.println("Login successful"); 
      LoggedInManager loggedin = connection.getLoggedInManager(); 
      System.out.println(loggedin); 
      String[] fileList = loggedin.getFileList(); 

      System.out.println(loggedin.getWorkingDirectory()); 

      if(fileList == null || fileList.length == 0) 
       System.out.println("No files found"); 
      else{ 
       for (String name : fileList) { 
        System.out.println(name); 
       } 
      } 

      connection.disconnect(); 

      if(connection.isDisconnected()) 
       System.out.println("Disconnection successful"); 
      else 
       System.out.println("Error disconnecting"); 
     }else{ 
      System.out.println("Unable to login"); 
     } 
    } else { 
     System.out.println("Could not connect"); 
    } 
} 

Produziert dieser Ausgabe:

Connected to FTP 
Login succesful 
[email protected] 
null 
No files found 
Disconnection successful 

Im Inneren der Umhüllung (versuchten beide listNames() und listFiles() verwenden):

 public String[] getFileList() { 
      String[] fileList = null; 
      FTPFile[] ftpFiles = null; 

      try { 
       ftpFiles = client.listFiles(); 
       //fileList = client.listNames(); 
       //System.out.println(client.listNames()); 
      } catch (IOException e) { 
       return null; 
      } 

      fileList = new String[ ftpFiles.length ]; 

      for(int i = 0; i < ftpFiles.length; i++){ 
       fileList[ i ] = ftpFiles[ i ].getName(); 
      } 

      return fileList; 
     } 

Was FtpClient wird wie folgt behandelt:

public class FTPUtils { 

private FTPClientManager clientManager; 

public FTPClientManager getFTPClientManager(){ 
    clientManager = new FTPClientManager(); 
    clientManager.setClient(new FTPClient()); 

    return clientManager; 
} 

Antwort

8

Jeder FTP-Server hat ein anderes Dateilistenlayout (ja, es ist nicht Teil des FTP-Standards, es ist dumm), und Sie müssen das korrekte FTPFileEntryParser verwenden, entweder indem Sie es manuell angeben, oder es CommonsFTP erlauben, erkenne es.

Automatische Erkennung funktioniert in der Regel gut, aber manchmal nicht, und Sie müssen es explizit angeben, z.

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX); 

FTPClient client = FTPClient(); 
client.configure(conf); 

Dies legt den erwarteten FTP-Servertyp explizit auf UNIX fest. Probieren Sie die verschiedenen Arten aus, sehen Sie, wie es geht. Ich versuchte, mich zu finden, aber ftp.belnet.be meine Verbindungen verweigert :(

+0

Danke. Wissen Sie, ob es möglich ist, die Rohlistenausgabe vor der Analyse zu erhalten? Belnet (belgisches Forschungsnetzwerk) könnte auch auf belgische ips beschränkt sein. Sie können ftp://c64.rulez.org versuchen. –

+1

@James: Sie könnten, denke ich, Ihre eigene Implementierung von 'FTPFileEntryParser' bereitstellen – skaffman

+0

übrigens ist der Standard Unix, wenn Sie den Konstruktor sehen, ist es wie diese öffentliche FTPClientConfig() { this (" UNIX "); } –

2

Haben Sie versucht, Überprüfung dass Sie die Dateien mit einem normalen FTP-Client auflisten können? (Aus irgendeinem Grunde kann ich nicht einmal auf den FTP-Port von „belnet.be“ anschließen.)

EDIT

Nach dem javadoc für listFiles() wird die Analyse der FTPFileEntryParser Instanz durch die vorgesehene Verwendung getan Parserfabrik. Wahrscheinlich müssen Sie herausfinden, welcher Parser mit der LIST-Ausgabe des FTP-Servers übereinstimmt und die Factory entsprechend konfigurieren.

+0

Ja. Die Dateien auf "belnet.be" werden in FileZilla angezeigt. Einige Ordner im Stammverzeichnis scheinen Verknüpfungen oder Verknüpfungen zu sein. Ich weiß nicht, ob das ein Problem sein könnte. Ich habe einen Dump der Verzeichnisliste hinzugefügt. –

+0

Danke. Die FTP-Adresse lautet ftp.belnet.be. –

1

Es gibt eine Parsing-Problem in früheren Version von Apache-Commons-net war, die SYST Befehl, der den Servertyp zurückgibt, wenn kehrt null (abrupt) wurde nicht in parsingException behandelt Versuchen Sie es mit dem letzten Glas von Apache-commons-net, das Ihr Problem lösen könnte.