2010-04-05 17 views
7

El método de org.apache.commons.net.ftp.FTPClientlistFiles() funciona bien con el servidor de Filezilla en 127.0.0.1 pero devuelve null en el directorio raíz de servidores FTP públicos como belnet.be.Problema con org.apache.commons.net.ftp.FTPClient listFiles()

Hay una pregunta idéntica en el siguiente enlace pero enterRemotePassiveMode() no parece ayudar. Apache Commons FTPClient.listFiles

¿Podría ser un problema con el análisis de listas? Si es así, ¿cómo puede solucionar esto?

Editar: Aquí hay un vertedero de caché de directorio:

FileZilla Directorio de caché Dump

Dumping 1 directorios en caché

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 

Aquí está mi código utilizando un envoltorio que he hecho (prueba dentro de la envoltura produce los mismos resultados):

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 esta salida:

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

Dentro de la envoltura (intentó usar tanto listNames() y 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; 
     } 

En cuanto a FtpClient, se maneja de la siguiente manera:

public class FTPUtils { 

private FTPClientManager clientManager; 

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

    return clientManager; 
} 

Respuesta

8

Cada servidor FTP tiene un diseño de lista de archivos diferente (sí, no es parte del estándar FTP, es tonto), por lo que debe usar el FTPFileEntryParser correcto, ya sea al especificarlo manualmente o al permitir que CommonsFTP se auto- detectarlo

La detección automática generalmente funciona bien, pero a veces no funciona, y debe especificarla explícitamente, p. Ej.

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX); 

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

Esto establece explícitamente el tipo de servidor FTP esperado en UNIX. Pruebe los distintos tipos, vea cómo funciona. He intentado encontrar a mí mismo, pero se niega ftp.belnet.be mis conexiones :(

+0

Gracias. ¿Sabes si es posible obtener la salida de la lista sin formato antes de analizarla? Además, Belnet (red de investigación belga) puede estar limitada a belgian ips. Puedes probar ftp://c64.rulez.org. –

+1

@James: Supongo que podría proporcionar su propia implementación de 'FTPFileEntryParser' – skaffman

+0

por la forma predeterminada Unix si ve el constructor es como este público FTPClientConfig() { this (" UNIX "); } –

2

Ha intentado comprobar que puede listar los archivos usando un cliente FTP normal? (Por alguna razón, no puedo incluso conectar al puerto FTP de "belnet.be".)

EDITAR

Según el Javadoc para listFiles(), el análisis se realiza mediante el FTPFileEntryParser ejemplo proporcionado por el analizador de fábrica Probablemente necesite averiguar cuál de los analizadores coincide con la salida LIST del servidor FTP y configurar la fábrica en consecuencia.

+0

Sí. Los archivos en belnet.be aparecen bien en FileZilla. Algunas carpetas en la raíz parecen ser atajos o enlaces. No sé si eso podría ser un problema. He agregado un volcado de la lista del directorio. –

+0

Gracias. Además, la dirección de ftp es ftp.belnet.be. –

1

Hubo un tema de análisis en la versión anterior de Apache-Commons-red, el comandoSIST que devuelve el tipo de servidor cuando devuelva null (bruscamente) no se manejó en la excepción de análisis. Intente usar el último jar jar de apache-commons-net que puede resolver su problema.