spring-boot - MultiResourceItemReader 未按预期工作
问题描述
我一直在FlatFileItemReader
一个一个地使用和处理文件。但我试图一次使用和提供所有文件,过滤后MultiResourceItemReader
有 3 个文件,最多 50 个。运行时即使提供了所有文件,如果我验证结果只有 1 个文件被处理。从文件中读取数据并保存到数据库中,在验证结果后,仅将 1 个文件的数据保存到数据库中。我找不到我做错了什么。我的代码如下:CSV
Job
CSV
MultiResourceItemReader
@Bean(name = "multiItemReader")
@StepScope
public MultiResourceItemReader<CDSBrokerBOIDMappingEntity> multiResourceItemReader(@Value("#{jobParameters[filenameStartPattern]}") String filenameStartPattern
, @Value("#{jobParameters[filenameEndPattern]}") String filenameEndPattern, @Value("#{jobParameters[localDirectory]}") String localDirectory) throws Exception {
String[] localDirectories = localDirectory.split(",");
List<Resource> inputResources = Collections.synchronizedList(new ArrayList<>());
for (String localDirectory1 : localDirectories){
try (Stream<Path> walk = Files.walk(Paths.get(localDirectory1), 1)) {
walk.filter(Files::isRegularFile) // is a file
.filter(p -> p.getFileName().toString().startsWith(filenameStartPattern) && p.getFileName().toString().endsWith(filenameEndPattern))
.findAny().ifPresentOrElse(f -> {
log.info("CSV FILE => " + f.getFileName().toString());
inputResources.add(new FileSystemResource(f));
},
() -> {
log.info("No file found");
});
} catch (IOException e) {
e.printStackTrace();
}
}
log.info("No. of files => "+inputResources.size());
MultiResourceItemReader<CDSBrokerBOIDMappingEntity> resourceItemReader = new MultiResourceItemReader<CDSBrokerBOIDMappingEntity>();
resourceItemReader.setResources(inputResources.toArray(Resource[]::new));
resourceItemReader.setDelegate(importReader());
resourceItemReader.setStrict(true);
return resourceItemReader;
}
FlatFileItemReader
代码是:
@Bean
public FlatFileItemReader<CDSBrokerBOIDMappingEntity> importReader() throws Exception {
FlatFileItemReader<CDSBrokerBOIDMappingEntity> reader = new FlatFileItemReader<>();
reader.setLinesToSkip(1);
reader.setLineMapper(new DefaultLineMapper<CDSBrokerBOIDMappingEntity>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[]{"BOID", "CLIENT_MEMBER_CODE", "BROKER_ID", "LAST_MODIFIED_DATE", "ISVALID"});
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<CDSBrokerBOIDMappingEntity>() {{
setTargetType(CDSBrokerBOIDMappingEntity.class);
}});
}});
reader.setStrict(true);
reader.afterPropertiesSet();
return reader;
}
作家是:
@Bean
public ItemWriter<CDSBrokerBOIDMappingEntity> writer() {
// log.info("Writer current thread. {}", Thread.currentThread().getName());
RepositoryItemWriter<CDSBrokerBOIDMappingEntity> writer = new RepositoryItemWriter<CDSBrokerBOIDMappingEntity>();
writer.setRepository(cdsBrokerBOIDMappingRepository);
// writer.setMethodName("save");
try {
writer.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
return writer;
}
和:Step
_Job
@Bean
public Job importUserJob(MultiResourceItemReader<CDSBrokerBOIDMappingEntity> importReader, JobCompletionNotificationListener listener) {
return jobBuilderFactory
.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1(importReader))
.end()
.build();
}
@Bean
public Step step1(@Qualifier("multiItemReader") MultiResourceItemReader<CDSBrokerBOIDMappingEntity> importReader) {
return stepBuilderFactory.get("step1").<CDSBrokerBOIDMappingEntity, CDSBrokerBOIDMappingEntity>chunk(200)
.reader(importReader)
.processor(processor())
.writer(writer())
.listener(stepListener())
.taskExecutor(taskExecutor())
.build();
}
我尝试了多次,但只读取了 1 个文件。代码有什么问题吗?还是我的方法不对?
解决方案
MultiResourceItemReader
使用 Spring Batch v4.3.3 可以按预期工作,这是一个简单的示例:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.mapping.PassThroughLineMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
@Configuration
@EnableBatchProcessing
public class SO68125366 {
@Bean
public MultiResourceItemReader<String> itemReader() {
FlatFileItemReader<String> itemReader = new FlatFileItemReaderBuilder<String>()
.name("itemReader")
.lineMapper(new PassThroughLineMapper())
.build();
MultiResourceItemReader<String> multiResourceItemReader = new MultiResourceItemReader<>();
multiResourceItemReader.setDelegate(itemReader);
Resource resource1 = new FileSystemResource("file1.txt");
Resource resource2 = new FileSystemResource("file2.txt");
multiResourceItemReader.setResources(new Resource[] {resource1, resource2});
return multiResourceItemReader;
}
@Bean
public ItemWriter<String> itemWriter() {
return items -> items.forEach(System.out::println);
}
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<String, String>chunk(5)
.reader(itemReader())
.writer(itemWriter())
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(SO68125366.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
有两个文件file1.txt
并file2.txt
分别包含hello
和world
,示例打印:
hello
world
这意味着MultiResourceItemReader
阅读两种资源,而不仅仅是你提到的一种。完整的示例可以在这个repo中找到。
推荐阅读
- java - java包和模块的允许名称
- android-studio - 更新到 Android Studio 3.5 版本后的新问题。运行应用程序时不会出现 ADB 设备选择屏幕 (SHIFT-F10)
- java - Maven、JavaFX、Launch4J-Maven-plugin - 如何捆绑 JRE?
- embedded-linux - 将 arm64 特定的内核头添加到 Linux 以刷新缓存
- reactjs - React Native Expo Offline App:如何从远程服务器更新本地数据库
- ruby-on-rails - 如何在更改与子表中不同记录的关系时触发销毁子项?
- ionic-framework - 升级 Ionic 3 - Ionic 4 CSS 复制问题
- batch-file - 如何将文件夹的每个子文件夹中除最新文件外的所有文件压缩为每个子文件夹一个 ZIP 文件?
- ruby - Ruby array.each 和 RestClient 跳过数组元素
- javascript - 模板文字在单引号中使用时为空