2010-04-05 12 views
7

Il metodo di org.apache.commons.net.ftp.FTPClientlistFiles() funziona bene con il server Filezilla su 127.0.0.1 ma restituisce null nella directory principale del server FTP pubblici come belnet.be.Problema con org.apache.commons.net.ftp.FTPClient ListFiles()

C'è una domanda identica sul link sottostante ma lo enterRemotePassiveMode() non sembra essere d'aiuto. Apache Commons FTPClient.listFiles

Potrebbe essere un problema con l'analisi delle liste? Se è così, come può andare a risolvere questo?

Edit: Ecco una discarica cache di directory:

FileZilla Directory Cache Dump

Dumping 1 directory cache

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 

Ecco il mio codice utilizzando un wrapper che ho fatto (test all'interno della confezione produce gli stessi risultati):

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"); 
    } 
} 

Produce questa uscita:

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

Dentro l'involucro (tentato utilizzando sia listNames() e listFiles()):

 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; 
     } 

Per quanto riguarda FTPClient, viene gestita come segue:

public class FTPUtils { 

private FTPClientManager clientManager; 

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

    return clientManager; 
} 

risposta

8

Ogni server FTP ha un layout di elenco file diverso (sì, non fa parte dello standard FTP, è stupido), quindi è necessario utilizzare lo FTPFileEntryParser corretto, specificandolo manualmente o consentendo a CommonsFTP di auto- rilevalo.

Il rilevamento automatico di solito funziona correttamente, ma a volte no, e devi specificarlo esplicitamente, ad es.

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX); 

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

Questo imposta esplicitamente il tipo di server FTP previsto su UNIX. Prova i vari tipi, guarda come va. Ho provato a scoprire me stesso, ma ftp.belnet.be rifiuta le mie connessioni :(

+0

Grazie. Sai se è possibile ottenere l'output della lista raw prima che venga analizzato? Inoltre, Belnet (rete di ricerca belga) potrebbe essere limitata agli IP belgi. Puoi provare ftp://c64.rulez.org. –

+1

@James: Si potrebbe, suppongo, di fornire la propria implementazione di 'FTPFileEntryParser' – skaffman

+0

dal modo in cui il valore predefinito è Unix se si vede il costruttore è come questo pubblico FTPClientConfig() { questo ("UNIX"); } –

2

Hai provato la verifica che puoi elencare i file usando il normale client FTP? (Per qualche ragione, non posso anche collegare alla porta FTP di "belnet.be".)

EDIT

Secondo javadoc per listFiles(), l'analisi viene eseguita utilizzando l'istanza FTPFileEntryParser fornito dal fabbrica di parser. Probabilmente è necessario capire quale parser corrisponde all'output LIST del server FTP e configurare di conseguenza la fabbrica.

+0

Sì. I file su belnet.be si presentano bene in FileZilla. Alcune cartelle nella radice sembrano essere scorciatoie o collegamenti. Non so se questo potrebbe essere un problema. Ho aggiunto un dump della lista delle directory. –

+0

Grazie. Inoltre, l'indirizzo ftp è ftp.belnet.be. –

1

C'è stato un problema di analisi nella precedente versione di Apache Commons-net, il comando diSYST che restituisce il tipo di server quando restituisce null (bruscamente) non è stato gestito in parsingException. Prova a utilizzare l'ultimo jar di apache-commons-net per risolvere il tuo problema.