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

Spring Batch如何读取多个同结构CSV文件?当前使用FlatFileItemReader

读取多个同结构CSV文件的Spring Batch解决方案

嘿,你说得没错,默认的FlatFileItemReader确实只能处理单个文件~不过Spring Batch专门为这种多文件场景提供了适配方案,下面给你两个实用的解决思路:

方案一:使用MultiResourceItemReader(最推荐)

这是Spring Batch官方针对多文件读取设计的组件,它可以把多个同结构文件资源交给底层的FlatFileItemReader逐个处理,完美匹配你的需求。

你可以把原来的FlatFileItemReader作为委托阅读器(delegate),再用MultiResourceItemReader包装它,示例代码如下:

@Bean
public FlatFileItemReader<HotelCSVDto> hotelCsvDelegateReader() {
    FlatFileItemReader<HotelCSVDto> reader = new FlatFileItemReader<>();
    // 这里不再设置单个资源,交给MultiResourceItemReader统一处理
    reader.setLineMapper(new DefaultLineMapper<HotelCSVDto>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            // 配置你的CSV分隔符、列名等规则
            setDelimiter(",");
            setNames(new String[]{"id", "name", "address", ...});
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<HotelCSVDto>() {{
            setTargetType(HotelCSVDto.class);
        }});
    }});
    // 保留你原来的RecordSeparatorPolicy配置
    reader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy(...));
    return reader;
}

@Bean
public MultiResourceItemReader<HotelCSVDto> multiHotelReader() throws IOException {
    MultiResourceItemReader<HotelCSVDto> reader = new MultiResourceItemReader<>();
    // 用路径匹配器批量获取BASE_PATH下符合规则的CSV文件
    Resource[] resources = new PathMatchingResourcePatternResolver()
            .getResources("classpath:" + BASE_PATH + "Hotels-*.csv");
    reader.setResources(resources);
    // 设置委托阅读器,由它处理单个文件的内容解析
    reader.setDelegate(hotelCsvDelegateReader());
    // 可选:设置为false的话,即使没找到匹配文件也不会直接报错
    reader.setStrict(false);
    return reader;
}

关键说明:

  • MultiResourceItemReader会遍历你指定的所有文件,逐个交给FlatFileItemReader解析,输出的HotelCSVDto数据和单个文件读取时完全一致
  • 可以通过路径匹配规则(比如*.csv)批量获取文件,不用手动逐个指定文件名
  • 原来的FlatFileItemReader配置(行映射、分隔策略等)完全可以复用,只需要移除单个资源的设置

方案二:动态传入文件列表(适合运行时指定文件)

如果你的文件路径需要在Job启动时动态指定(比如通过参数传递),可以用StepScope结合JobParameters实现:

@Bean
@StepScope
public MultiResourceItemReader<HotelCSVDto> dynamicMultiHotelReader(
        @Value("#{jobParameters['filePaths']}") String filePaths) {
    MultiResourceItemReader<HotelCSVDto> reader = new MultiResourceItemReader<>();
    // 把传入的逗号分隔文件路径转成Resource数组
    Resource[] resources = Arrays.stream(filePaths.split(","))
            .map(path -> new ClassPathResource(path))
            .toArray(Resource[]::new);
    reader.setResources(resources);
    reader.setDelegate(hotelCsvDelegateReader());
    return reader;
}

启动Job时通过参数传递多个文件路径:

JobParameters jobParameters = new JobParametersBuilder()
        .addString("filePaths", BASE_PATH + "Hotels-NY.csv," + BASE_PATH + "Hotels-LA.csv")
        .toJobParameters();
jobLauncher.run(hotelJob, jobParameters);

注意事项

  • 确保所有CSV文件的结构完全一致(列数、列顺序、数据类型),否则FieldSetMapper会抛出转换异常
  • 如果处理大文件,建议开启Spring Batch的Chunk分片处理,避免内存溢出
  • 若每个文件都有表头,可以在委托阅读器中用setSkippedLinesCount(1)跳过第一行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:26:41