如何通过Spring Integration File读取嵌套目录下的txt文件
嵌套子目录扫描适配方案
1. 启用文件入站适配器的递归扫描能力
现有fileInboundChannelFlow Bean中,文件入站适配器默认仅扫描根入站目录的直属文件,需要补上递归扫描的开启逻辑,调整后的代码片段:
@Bean public IntegrationFlow fileInboundChannelFlow() { FileInboundChannelAdapterSpec messageSourceSpec = Files .inboundAdapter(Paths.get(this.properties.getDirectory()).toFile()) // 开启根目录下所有层级嵌套子目录的递归扫描 .scanRecursive(true) // 补充目录遍历规则,跳过符号链接避免递归死循环 .directoryFilter(file -> !Files.isSymbolicLink(file.toPath())); // 保留原有过滤器、去重逻辑 messageSourceSpec = messageSourceSpec.filter(getFilter()); messageSourceSpec.preventDuplicates(this.properties.isPreventDuplicates()); // 保留原有文件拆分、Kafka消息头增强逻辑,无需调整 IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(messageSourceSpec) .split(new FileSplitter(true, true)) .enrichHeaders(h -> h.headerExpression(KafkaHeaders.MESSAGE_KEY,"T(java.util.UUID).randomUUID().toString()")); // 保留原有路由逻辑,无需调整 return flowBuilder.<Object, Class<?>>route(Object::getClass, m -> m.channelMapping(FileSplitter.FileMarker.class, "markers.input").channelMapping(String.class, "lines.input")) .get(); }
2. 修复自定义过滤器的递归场景兼容问题
当前编写的DynamicRegexPatternFilter存在两个适配问题,开启递归扫描后会触发运行异常:
- 递归扫描时适配器会同时遍历目录实体,原有逻辑没有区分文件和目录,会把符合正则规则的子目录当成普通文件尝试读取,直接抛出文件读取异常
- 现有Bean定义是手动
new过滤器实例,类上的@Autowired注解无法被Spring容器识别生效,会出现properties空指针问题
调整后的过滤器代码:
public class DynamicRegexPatternFilter extends AbstractFileListFilter<File> { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicRegexPatternFilter.class); private FileSourceProperties properties; // 构造方法注入属性,避免手动初始化时空指针 public DynamicRegexPatternFilter(FileSourceProperties properties) { this.properties = properties; } @Override public boolean accept(File file) { // 递归扫描场景下,直接跳过所有目录实体,避免误处理 if (file.isDirectory()) { return false; } // 补充txt文件后缀判断,匹配读取txt类型文件的需求 if (!file.getName().endsWith(".txt")) { return false; } String fileNameRegex = this.properties.getFilenameRegex(); // 保留原有文件名正则匹配逻辑 return Pattern.compile(fileNameRegex) .matcher(file.getName()) .matches(); } }
同步调整原来的过滤器Bean定义,替换手动初始化的逻辑:
@Bean public DynamicRegexPatternFilter getFilter(FileSourceProperties properties){ // 传入properties实例,保证过滤器逻辑正常运行 return new DynamicRegexPatternFilter(properties); }
3. 配套注意事项
- 原有
preventDuplicates去重逻辑无需调整:递归扫描时每个文件的全路径是唯一标识,原有去重机制会正常拦截重复读取的文件,不会出现同一文件被多次投递到Kafka的问题。 - 原有文件拆分、消息头增强、错误日志、文件归档的流程逻辑完全不需要改动,这些组件只处理文件流内容,不依赖文件的所在目录层级。
- 如果后续需要跳过指定子目录(比如临时缓存目录、归档目录),可以在之前配置的
directoryFilter里补充判断规则,比如跳过名称包含temp的目录,直接返回false即可。
调整完成后,适配器会自动扫描inbound根目录下所有层级子目录里的符合正则规则的txt文件,inbound/a/a.txt、inbound/b/b.txt这类路径的文件都会被正常读取投递。
内容的提问来源于stack exchange,提问作者Hasnain Ali Bohra
相关产品推荐
相关产品推荐

