Apache Commons Net FTPClient和listFiles()

41

有人能解释一下以下代码的问题吗?我尝试了不同的主机和FTPClientConfigs,通过firefox/filezilla可以正常访问...问题是我总是得到空文件列表而没有任何异常(files.length == 0)。我使用的是通过Maven安装的commons-net-2.1.jar。

    FTPClientConfig config = new FTPClientConfig(FTPClientConfig.SYST_L8);

    FTPClient client = new FTPClient();
    client.configure(config);

    client.connect("c64.rulez.org");
    client.login("anonymous", "anonymous");
    client.enterRemotePassiveMode();

    FTPFile[] files = client.listFiles();
    Assert.assertTrue(files.length > 0);

有任何错误信息吗?不确定你的问题是什么! - Guillaume
问题是我总是得到一个空的文件列表,没有任何异常(files.length == 0)。问题已更新。 - Vladimir Mihailenco
1
它在我的FTP服务器上运行得很好,只是我没有调用client.configure(...)。 - Guillaume
我也尝试了ftp.belnet.be / ftp.ccc.uba.ar以及一些私人FTP服务器,但即使没有client.configure,我也无法让它正常工作...我还尝试禁用Windows防火墙和杀毒软件...你能分享一些可用的FTP主机吗? - Vladimir Mihailenco
ftp4j的基本示例可以正常工作,但我想知道我的commons-net代码有什么问题... - Vladimir Mihailenco
4个回答

101

找到了!

问题在于你需要在连接后但登录前进入被动模式。 你的代码对我无效,但以下代码对我有效:

import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
import org.apache.commons.net.ftp.FTPFile;

public class BasicFTP {

    public static void main(String[] args) throws IOException {
        FTPClient client = new FTPClient();
        client.connect("c64.rulez.org");
        client.enterLocalPassiveMode();
        client.login("anonymous", "");
        FTPFile[] files = client.listFiles("/pub");
        for (FTPFile file : files) {
            System.out.println(file.getName());
        }
    }
}

这个命令会给我以下输出结果:

c128
c64
c64.hu
incoming
plus4

1
(关于BTW评论:Assert.assertTrue来自JUnit或TestNG;Java的assert只是assert。无论如何,我想重点只是为了向问题的读者说明期望的结果。) - Jonik
@Jonik 哦,没错。我没注意到。我已经删除了那一部分。 - PapaFreud
有本地被动、远程被动、本地主动、远程主动四种方式,我一个接一个地尝试了它们,最终本地被动生效了。 - Junchen Liu
非常感谢你,亲爱的朋友。我在所有网站上搜索了,但无法找到解决这个问题的方法。你的代码救了我!太棒了。 - Rajesh Kumar Yadav

14

仅使用enterLocalPassiveMode()对我没有起作用。

我使用了以下代码,它有效。

    ftpsClient.execPBSZ(0);
    ftpsClient.execPROT("P");
    ftpsClient.type(FTP.BINARY_FILE_TYPE);

完整的示例如下所示,

    FTPSClient ftpsClient = new FTPSClient();        

    ftpsClient.connect("Host", 21);

    ftpsClient.login("user", "pass");

    ftpsClient.enterLocalPassiveMode();

    ftpsClient.execPBSZ(0);
    ftpsClient.execPROT("P");
    ftpsClient.type(FTP.BINARY_FILE_TYPE);

    FTPFile[] files = ftpsClient.listFiles();

    for (FTPFile file : files) {
        System.out.println(file.getName());
    }

找不到方法:ftpClient.execPBSZ(0); ftpClient.execPROT("P") - Kamil Nękanowicz
你正在使用FTPClient还是FTPSClient?这些方法只存在于FTPSClient中。 - suketup

3
通常匿名用户不需要密码,尝试:
client.login("anonymous", "");

0

对我而言,当我在调用ftpClient.listFiles()之前使用ftpClient.enterLocalPassiveMode()时,它是有效的。 下面是完整的代码:

                final List<String> files = new ArrayList<>();
                try {
                    ftpClient.enterLocalPassiveMode();
                    String[] f = null;
                    if (parentDir.isEmpty()) {
                        f = ftpClient.listNames();
                    }else{
                        f = ftpClient.listNames(parentDir);
                    }
                    for (String s :f ) {
                        files.add(s);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    postError(e.getMessage()!= null?e.getMessage():e.toString());
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接