Spring Batch单输入文件拆分多输出文件的高效实现咨询
用Spring Batch实现单Step多文件输出(一次读入,按数据路由)
针对你要一次读取输入文件、按行数据特征分写到5个输出文件的需求,直接用Spring Batch提供的ClassifierCompositeItemWriter就能搞定,不需要多Step重复读文件,具体实现步骤如下:
1. 定义单个输出文件的Writer
先为每个输出文件创建独立的FlatFileItemWriter,配置各自的输出路径和数据格式:
@Bean public FlatFileItemWriter<YourDataModel> outputWriter1() { return new FlatFileItemWriterBuilder<YourDataModel>() .name("outputWriter1") .resource(new FileSystemResource("path/to/output1.csv")) .lineAggregator(new DelimitedLineAggregator<YourDataModel>() {{ setDelimiter(","); setFieldExtractor(new BeanWrapperFieldExtractor<YourDataModel>() {{ // 替换成你的数据类字段名 setNames(new String[]{"id", "type", "content"}); }}); }}) .encoding("UTF-8") .build(); } // 同理创建outputWriter2到outputWriter5,每个对应不同的输出文件路径
2. 实现数据分类器
自定义一个Classifier,根据每行数据的特征判断该路由到哪个Writer:
@Component public class DataTypeClassifier implements Classifier<YourDataModel, ItemWriter<? super YourDataModel>> { private final Map<String, ItemWriter<? super YourDataModel>> writerMapping; // 构造注入所有单个Writer public DataTypeClassifier(FlatFileItemWriter<YourDataModel> outputWriter1, FlatFileItemWriter<YourDataModel> outputWriter2, FlatFileItemWriter<YourDataModel> outputWriter3, FlatFileItemWriter<YourDataModel> outputWriter4, FlatFileItemWriter<YourDataModel> outputWriter5) { writerMapping = new HashMap<>(); // 这里的key要和你的数据类型匹配,比如数据里的type字段值 writerMapping.put("TYPE_A", outputWriter1); writerMapping.put("TYPE_B", outputWriter2); writerMapping.put("TYPE_C", outputWriter3); writerMapping.put("TYPE_D", outputWriter4); writerMapping.put("TYPE_E", outputWriter5); } @Override public ItemWriter<? super YourDataModel> classify(YourDataModel item) { // 根据你的数据逻辑判断类型,比如取item.getType() String dataType = item.getType(); // 可选:设置默认Writer处理未匹配的数据 return writerMapping.getOrDefault(dataType, outputWriter1); } }
3. 配置复合Writer
把分类器和单个Writer整合到ClassifierCompositeItemWriter中:
@Bean public ClassifierCompositeItemWriter<YourDataModel> compositeWriter(DataTypeClassifier classifier) { ClassifierCompositeItemWriter<YourDataModel> compositeWriter = new ClassifierCompositeItemWriter<>(); compositeWriter.setClassifier(classifier); return compositeWriter; }
4. 组装单Step
最后创建一个Step,只读取一次输入文件,通过复合Writer完成多文件输出:
@Bean public Step splitFileStep(ItemReader<YourDataModel> inputReader, // 不需要数据处理的话,这里可以不传processor,直接去掉该参数 ItemProcessor<YourDataModel, YourDataModel> dataProcessor, ClassifierCompositeItemWriter<YourDataModel> compositeWriter, JobRepository jobRepository, PlatformTransactionManager transactionManager) { return new StepBuilder("splitFileStep", jobRepository) .<YourDataModel, YourDataModel>chunk(100, transactionManager) // Chunk大小按需调整 .reader(inputReader) .processor(dataProcessor) .writer(compositeWriter) .build(); }
关键说明
- 整个Step只执行一次文件读取操作,每行数据通过分类器自动路由到对应输出文件,避免了多Step重复读的效率问题。
- 可以根据需求调整Chunk大小,平衡内存占用和处理效率。
- 若需要处理文件追加、表头写入等细节,可在
FlatFileItemWriter中添加append(true)、headerCallback等配置。
内容的提问来源于stack exchange,提问作者Hurtcraft
相关产品推荐
相关产品推荐

