Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
449 views
in Technique[技术] by (71.8m points)

java - Issue with org.apache.commons.net.ftp.FTPClient listFiles()

The listFiles() method of org.apache.commons.net.ftp.FTPClient works fine with Filezilla server on 127.0.0.1 but returns null on the root directory of public FTP servers such as belnet.be.

There is an identical question on the link below but enterRemotePassiveMode() doesn't seem to help. Apache Commons FTPClient.listFiles

Could it be an issue with list parsing? If so, how can go about solving this?

Edit: Here's a directory cache dump:

FileZilla Directory Cache Dump

Dumping 1 cached directories

Entry 1:
Path: /
Server: anonymous@ftp.belnet.be: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

Here's my code using a wrapper I've made (testing inside the wrapper produces the same results):

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

Produces this output:

Connected to FTP
Login succesful
utils.ftp.FTPClientManager$Connection$LoggedInManager@156ee8e
null
No files found
Disconnection successful

Inside the wrapper (attempted using both listNames() and 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;
        }

As for FTPClient, it is handled as follows:

public class FTPUtils {

private FTPClientManager clientManager;

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

    return clientManager;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Each FTP server has a different file list layout (yes, it's not part of the FTP standard, it's dumb), and so you have to use the correct FTPFileEntryParser, either by specifying it manually, or allowing CommonsFTP to auto-detect it.

Auto-detection usually works fine, but sometimes it doesn't, and you have to specify it explicitly, e.g.

FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);

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

This explicitly sets the expected FTP server type to UNIX. Try the various types, see how it goes. I tried finding out myself, but ftp.belnet.be is refusing my connections :(


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...