能够读取多个文件,然后为每个源文件写入内容

时间:2017-07-14 17:54:52

标签: spring spring-boot spring-batch

读取文件工作正常,但写入文件却不行。

我想阅读多个文件,然后使用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;
    }

请注意,这就像从源文件夹复制并粘贴到目标文件夹。

3 个答案:

答案 0 :(得分:0)

有两种方法 -

  1. 通过扩展multiresourceitemreader编写自定义阅读器,然后在read()方法中,您可以获取当前的源文件名。然后将此文件设置为csvFoo并动态传递此源文件名为作者。

  2. 写一个额外的步骤和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();
    }

}

并将srcDirdstDir作为工作参数传递。

答案 2 :(得分:0)

解决您问题的简单方法 - 为什么不为每个源文件创建步骤。鉴于并基于您的方案,文件源和目标是一对一的。 MultiResourceItemWriter只是一种创建新输出文件的方法,一旦达到你设置的限制setItemCountLimitPerResource(int)(我在你的例子中找不到)。如果没有性能问题,如果没有依赖关系或序列,您甚至可以并行运行这些步骤。