如何过滤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
相关产品推荐
相关产品推荐

