org.apache.commons.net.ftp.FTPClient listFiles() 的问题
org.apache.commons.net.ftp.FTPClient
的 listFiles()
方法在 127.0.0.1 上的 Filezilla 服务器上运行良好,但返回 null
位于公共 FTP 服务器(例如 belnet.be)的根目录下。
下面的链接有一个相同的问题,但 enterRemotePassiveMode()
似乎没有帮助。 Apache Commons FTPClient.listFiles
这可能是列表解析的问题吗?如果是这样,如何解决这个问题?
编辑:这是一个目录缓存转储:
FileZilla目录缓存转储
转储1个缓存目录
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
这是我使用我制作的包装器的代码(在包装器内部测试产生相同的结果):
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" );
}
}
产生此输出:
Connected to FTP
Login succesful
utils.ftp.FTPClientManager$Connection$LoggedInManager@156ee8e
null
No files found
Disconnection successful
在包装器内部(尝试使用两个 listNames()
和 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;
}
对于FTPClient,处理如下:
public class FTPUtils {
private FTPClientManager clientManager;
public FTPClientManager getFTPClientManager(){
clientManager = new FTPClientManager();
clientManager.setClient( new FTPClient() );
return clientManager;
}
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每个 FTP 服务器都有不同的文件列表布局(是的,它不是 FTP 标准的一部分,它很愚蠢),因此您必须使用正确的 FTPFileEntryParser,要么手动指定,要么允许 CommonsFTP自动检测它。
自动检测通常工作得很好,但有时却不能,你必须明确指定它,例如,
这明确地将预期的 FTP 服务器类型设置为 UNIX。尝试各种类型,看看效果如何。我尝试自己找出答案,但
ftp.belnet.be
拒绝我的连接:(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.
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 :(您是否尝试过检查是否可以使用普通 FTP 客户端列出文件? (由于某种原因,我什至无法连接到“belnet.be”的 FTP 端口。)
编辑
根据 listFiles(),解析是使用 FTPFileEntryParser 解析器工厂提供的实例。您可能需要找出哪个解析器与 FTP 服务器的 LIST 输出匹配,并相应地配置工厂。
Have you tried checking that you can list the files using normal FTP client? (For some reason, I cannot even connect to the FTP port of "belnet.be".)
EDIT
According to the javadoc for listFiles(), the parsing is done using the FTPFileEntryParser instance provided by the parser factory. You probably need to figure out which of the parsers matches the FTP server's LIST output and configure the factory accordingly.
早期版本的 apache-Commons-net 存在解析问题,当返回 null(突然)时返回服务器类型的 SYST 命令未在 parsingException 中处理。尝试使用 apache-commons-net 的 最新 jar 它可能会解决您的问题。
There was a parsing issue in earlier version of apache-Commons-net , the SYST command which returns the server type when returns null ( abruptly ) was not handled in parsingException . Try using the latest jar of apache-commons-net it may solve your problem.