我正在使用Spring Batch处理平面文件,但我遇到了问题 - 有时我必须等待文件中的流 - 因为文件是通过网络写的。现在,当FlatFileReader
读取空行时,步骤具有退出状态COMPLETE。有没有办法在Reader中等待下一行,或者在无限循环中重复使用当前行的步骤?
我正在使用Java Config,所以我的代码是:
@Bean
public Job importUserJob() {
Job job = jobBuilders.get("importUserJob").incrementer(new RunIdIncrementer()).flow(step1()).end().build();
return job;
}
我发现当我使用时:
Job job = jobBuilders.get("importUserJob").incrementer(new RunIdIncrementer()).flow(step1()).next(step1()).end().build();
然后step1在无限循环中运行,但在每个循环中它从文件的begginig读取。
如果读取行为空或等待行,可能是另一种重试步骤的方法? 也许问题是我在内置hsqldb内存?
答案 0 :(得分:1)
解决方案是在第一步下载文件并在第二步中处理它 这是首选,因为您可以重新启动/继续处理而无需再次下载文件,并且您不会遇到超时/重试问题。
答案 1 :(得分:0)
FlatFileItemReader
期望文件在开始处理之前已完全写入。如果文件仍在写入,您应该等到它完成后再开始工作。
答案 2 :(得分:0)
我这样解决了我的问题: 1.创建SystemCommandTasklet:
@Bean
public Step waitStep() {
SystemCommandTasklet tasklet = new SystemCommandTasklet();
tasklet.setCommand("sleep 30");
tasklet.setTimeout(31000);
return stepBuilders.get("waitStep").tasklet(tasklet).allowStartIfComplete(true).build();
}
创建自定义ItemReader几乎与FlatFileItemReader相同,但我添加了这个:
private String readLine() {
if (reader == null) {
throw new ReaderNotOpenException("Reader must be open before it can be read.");
}
String line = null;
try {
line = this.reader.readLine();
if (line == null) {
//this is most interesting line
setLinesToSkip(lineCount);
return null;
}
lineCount++;
while (isComment(line)) {
line = reader.readLine();
if (line == null) {
return null;
}
lineCount++;
}
line = applyRecordSeparatorPolicy(line);
}
catch (IOException e) {
// Prevent IOException from recurring indefinitely
// if client keeps catching and re-calling
noInput = true;
throw new NonTransientFlatFileException("Unable to read from resource: [" + resource + "]", e, line,
lineCount);
}
return line;
}
然后在我的JobBuilder中:
Job job = jobBuilders.get("importUserJob").incrementer(new RunIdIncrementer()).flow(step1()).next(waitStep()).next(step1()).end().build();
这正是我所寻找的。现在我的step1正在运行,当我的流结束时,waitStep正在运行(等待30秒),然后step1正在运行,但跳过先前读取的行。一遍又一遍; - )