问题
i am currently in process of learning spring batch and i have been challenged with a task of file archiving. Basically i need to read separate CSV files and put them in a new archived folder with the original filename appended with the current date. What i want to know is how i can get the original filename from the multiResourceItemReader, use it in the FlatfileItemWriter as the filename + date and deleting the original file afterwards.
Here's my current code:
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Value("classpath*:/data/CSV_FOR_ARCHIVING*.csv")
private Resource inputFiles[];
@Bean
public MultiResourceItemReader<Person> multiResourceItemReader() {
MultiResourceItemReader<Person> itemReader = new MultiResourceItemReader<>();
itemReader.setDelegate(personItemReader());
itemReader.setResources(inputFiles);
return itemReader;
}
@Bean
public FlatFileItemReader<Person> personItemReader() {
FlatFileItemReader<Person> itemReader = new FlatFileItemReader<>();
itemReader.setLinesToSkip(1);
DefaultLineMapper<Person> personLineMapper = new DefaultLineMapper<>();
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
tokenizer.setNames(new String[] { "id", "firstName", "lastName", "email", "gender" });
personLineMapper.setLineTokenizer(tokenizer);
personLineMapper.setFieldSetMapper(new PersonFieldSetMapper());
personLineMapper.afterPropertiesSet();
itemReader.setLineMapper(personLineMapper);
return itemReader;
}
@Bean
public FlatFileItemWriter<Person> jsonWriter() throws Exception {
FlatFileItemWriter<Person> personWriter = new FlatFileItemWriter<>();
personWriter.setLineAggregator(new PersonLineAggregator());
File outputPath = File.createTempFile("PersonOutput", ".csv", new File("C:/Users/default/Documents"));
System.out.println("Output Path: " + outputPath.getAbsolutePath());
personWriter.setResource(new FileSystemResource(outputPath));
personWriter.afterPropertiesSet();
return personWriter;
}
@Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1").<Person, Person>chunk(10)
.listener(new ItemReaderListener())
.reader(multiResourceItemReader())
.writer(jsonWriter())
.build();
}
@Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job")
.start(step1())
.build();
}
CSV files to be readed and archived separately
EDIT 1: Thanks for the answer @Niraj, i've implemented the ResourceAware and i can already get the filename. Now my new question is how do i tell my FlatFileItemWriter to create and write on a new file each time the resource has changed?
回答1:
Use ResourceAware interface to get the current file name. And ResourceSuffixCreator interface to create suffix as per you need
http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/ResourceAware.html http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/ResourceSuffixCreator.html
回答2:
You can put the value in executionContext from your reader and read in your writer. Something like this
@Value("#{jobExecution.executionContext}")
private ExecutionContext executionContext;
public void somePlaceInYourReader(){
this.executionContext.putInt("fileName", fileName);
}
And read it the same way using executionContext.getInt("fileName"). You might have to use this as well @JobScope
来源:https://stackoverflow.com/questions/44455863/spring-batch-file-archiving