Apache Camel FTP 如何获取FTP目录下所有文件及文件夹的元数据列表
解决方案
你可以直接通过Apache Camel FTP组件的原生配置实现需求,无需自行封装FTPClient,具体步骤如下:
1 调整FTP端点配置
核心是开启文件夹扫描、关闭文件内容下载,参考配置参数:
passiveMode=true:建议开启,避免多数网络环境下的FTP连接阻塞问题includeDirectories=true:关键配置,关闭默认跳过文件夹的逻辑,返回目录项download=false:仅拉取文件/文件夹元数据,不会下载实际内容,执行效率极高recursive=true:按需开启,若需要遍历所有层级子目录则开启,仅扫描当前目录可设为falseidempotent=false:关闭幂等校验,避免二次扫描时因历史记录遗漏条目
2 解决聚合完成判定问题
Camel FTP消费者完成单次全量扫描后,会自动在最后一个Exchange的头部添加CamelBatchComplete标识,你可以直接用该标识作为聚合完成的判定条件,无需提前预知文件总数。
以下是Java DSL的参考实现:
// 自定义聚合策略,把所有FTP子项元数据存入列表 AggregationStrategy ftpListAggregationStrategy = (oldExchange, newExchange) -> { if (oldExchange == null) { List<Map<String, Object>> list = new ArrayList<>(); list.add(extractMetadata(newExchange)); newExchange.getIn().setBody(list); return newExchange; } List<Map<String, Object>> list = oldExchange.getIn().getBody(List.class); list.add(extractMetadata(newExchange)); return oldExchange; }; // 元数据提取方法,按需取你需要的字段 private Map<String, Object> extractMetadata(Exchange exchange) { Map<String, Object> meta = new HashMap<>(); meta.put("fileName", exchange.getIn().getHeader("CamelFileName", String.class)); meta.put("filePath", exchange.getIn().getHeader("CamelFilePath", String.class)); meta.put("size", exchange.getIn().getHeader("CamelFileLength", Long.class)); meta.put("lastModified", exchange.getIn().getHeader("CamelFileLastModified", Long.class)); meta.put("isDirectory", exchange.getIn().getHeader("CamelFileType", String.class).equals("directory")); return meta; } // 路由示例 from("direct:fetchFtpList") .pollEnrich("ftp://username@host:port/remotePath?password=xxx&passiveMode=true&includeDirectories=true&download=false&recursive=true&idempotent=false", 5000, // 超时时间按需调整 ftpListAggregationStrategy, false) // 聚合完成后拿到的body就是完整的元数据列表,可直接用于和本地目录比对生成报表 .process(exchange -> { List<Map<String, Object>> fullFtpList = exchange.getIn().getBody(List.class); // 你的比对逻辑 });
补充说明
如果只需要获取当前目录的一级子项,把配置里的recursive设为false即可;如果有过滤不需要的文件/目录的需求,可以追加filter参数配置自定义过滤器,不会影响全量扫描逻辑。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

