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

Apache Camel FTP 如何获取FTP目录下所有文件及文件夹的元数据列表

解决方案

你可以直接通过Apache Camel FTP组件的原生配置实现需求,无需自行封装FTPClient,具体步骤如下:

1 调整FTP端点配置

核心是开启文件夹扫描、关闭文件内容下载,参考配置参数:

  • passiveMode=true:建议开启,避免多数网络环境下的FTP连接阻塞问题
  • includeDirectories=true:关键配置,关闭默认跳过文件夹的逻辑,返回目录项
  • download=false:仅拉取文件/文件夹元数据,不会下载实际内容,执行效率极高
  • recursive=true:按需开启,若需要遍历所有层级子目录则开启,仅扫描当前目录可设为false
  • idempotent=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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 02:06:03