You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤FTPClient listFiles返回结果以仅获取文件?

解决FTPClient获取仅文件列表的问题

首先,你遇到的目录重复问题,是因为client.listFiles(directory)默认会返回所有文件和目录,而你又同时传入了client.listDirectories()的结果,相当于目录被重复添加了两次。另外,Apache Commons Net的FTPFileFilters确实没有提供现成的"仅文件"过滤器,但我们可以轻松自定义一个,或者手动过滤出文件。

方案1:自定义FILES过滤器(推荐)

模仿FTPFileFilters里的DIRECTORIES实现,我们可以自己写一个仅匹配文件的过滤器:

public class CustomFTPFileFilters {
    /**
     * Accepts all (non-null) FTPFile file entries.
     */
    public static final FTPFileFilter FILES = new FTPFileFilter() {
        @Override
        public boolean accept(FTPFile file) {
            return file != null && file.isFile();
        }
    };
}

然后修改你的downloadDirectory方法,用这个过滤器调用listFiles,这样得到的就是纯文件列表,再配合listDirectories获取纯目录列表,就不会出现重复了:

public void downloadDirectory(String directory) {
    try {
        client.setFileType(FTP.BINARY_FILE_TYPE);
        FileData.getInstance().loadDirectoryContents(
                client.listFiles(directory, CustomFTPFileFilters.FILES), // 仅获取文件
                client.listDirectories(directory)); // 仅获取目录,建议传入directory参数避免默认根目录
    } catch (IOException e) {
        // 这里补充异常处理逻辑,比如日志打印
        e.printStackTrace();
    }
}

方案2:手动过滤文件列表

如果不想新增过滤器类,也可以在获取所有条目后手动筛选出文件:

public void downloadDirectory(String directory) {
    try {
        client.setFileType(FTP.BINARY_FILE_TYPE);
        FTPFile[] allEntries = client.listFiles(directory);
        List<FTPFile> onlyFiles = new ArrayList<>();
        for (FTPFile entry : allEntries) {
            if (entry != null && entry.isFile()) {
                onlyFiles.add(entry);
            }
        }
        // 转换为数组传给FileData
        FTPFile[] fileArray = onlyFiles.toArray(new FTPFile[0]);
        FileData.getInstance().loadDirectoryContents(
                fileArray,
                client.listDirectories(directory));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

关于FTPClient设计的小说明

你疑惑为什么有listDirectories和DIRECTORIES过滤器却没有对应文件的方法,其实这是因为文件的过滤需求更灵活(比如按文件后缀、大小筛选),官方没有提供单一的"仅文件"过滤器,但通过自定义或手动过滤完全可以满足需求。而listDirectories只是一个快捷方法,本质上也是内部用了DIRECTORIES过滤器来实现的。

内容的提问来源于stack exchange,提问作者chrips

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:11:42