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: [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
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;
}
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 :(