读取文件工作正常,但写入文件却不行。
我想阅读多个文件,然后使用MultiResourceItemWriter
分别编写,例如:
读取文件:
source/abc.csv
source/cbd.csv
source/efg.csv
应该分开写文件,如:
target/abc.csv
target/cbd.csv
target/efg.csv
但目前它正在将所有数据放在一个文件中。
@Bean
public MultiResourceItemWriter<FooCsv> multipleCsvWriter(@Value("${directory.destination}") Resource folder) throws Exception {
MultiResourceItemWriter<FooCsv> writer = new MultiResourceItemWriter<>();
writer.setResource(folder);
writer.setDelegate(csvWriter(file));
return writer;
}
请注意,这就像从源文件夹复制并粘贴到目标文件夹。
答案 0 :(得分:0)
有两种方法 -
通过扩展multiresourceitemreader编写自定义阅读器,然后在read()方法中,您可以获取当前的源文件名。然后将此文件设置为csvFoo并动态传递此源文件名为作者。
写一个额外的步骤和taskley,它将列出所有可用的源文件,然后将它们添加到作业参数,并将源和目标文件名动态传递到下一步,并循环调用此步骤,直到所有列表文件都不进行
答案 1 :(得分:0)
您可以使用MultiResourcePartitioner
来实现相同目标。以下是批量配置示例
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private ResourcePatternResolver resourcePatternResolver;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
public DataSource dataSource;
@Autowired
ApplicationContext context;
@Bean
@JobScope
public MultiResourcePartitioner paritioner(@Value("#{jobParameters[srcDir]}") String src) throws IOException {
Resource[] resources = resourcePatternResolver.getResources(src);
MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
partitioner.partition(1);
partitioner.setResources(resources);
return partitioner;
}
@Bean
@StepScope
public FlatFileItemReader<String> reader(@Value("#{stepExecutionContext[fileName]}") Resource file) {
FlatFileItemReader<String> reader = new FlatFileItemReader<String>();
reader.setResource(file);
reader.setLineMapper(new PassThroughLineMapper());
return reader;
}
@Bean
@StepScope
public FlatFileItemWriter<String> writer(@Value("#{jobParameters[destDir]}") String dest,
@Value("#{stepExecutionContext[fileName]}") Resource file) {
String destFile = dest + file.getFilename();
System.out.println(destFile);
FlatFileItemWriter<String> writer = new FlatFileItemWriter<String>();
writer.setLineAggregator(new PassThroughLineAggregator<>());
writer.setResource(resourcePatternResolver.getResource(destFile));
return writer;
}
@Bean
public Job kpJob() {
return jobBuilderFactory.get("kpJob").incrementer(new RunIdIncrementer()).flow(step1()).end().build();
}
@Bean
public Step step1() {
Partitioner partitioner = context.getBean(MultiResourcePartitioner.class);
return stepBuilderFactory.get("step1").partitioner(slaveStep()).partitioner("step1.slave", partitioner).build();
}
@Bean
public Step slaveStep() {
ItemReader<String> reader = context.getBean(FlatFileItemReader.class);
ItemWriter<String> writer = context.getBean(FlatFileItemWriter.class);
return stepBuilderFactory.get("step1.slave").<String, String>chunk(10).reader(reader).writer(writer).build();
}
}
并将srcDir
和dstDir
作为工作参数传递。
答案 2 :(得分:0)
解决您问题的简单方法 - 为什么不为每个源文件创建步骤。鉴于并基于您的方案,文件源和目标是一对一的。 MultiResourceItemWriter
只是一种创建新输出文件的方法,一旦达到你设置的限制setItemCountLimitPerResource(int)
(我在你的例子中找不到)。如果没有性能问题,如果没有依赖关系或序列,您甚至可以并行运行这些步骤。