Java Spring批处理在平面文件中等待行

Java Spring批处理在平面文件中等待行,java,spring,spring-batch,Java,Spring,Spring Batch,我正在用SpringBatch处理一个平面文件,但我有一个问题——有时我必须等待文件中的流——因为文件是通过网络写入的。现在,当FlatFileReader读取空行时,步骤的退出状态已完成。有没有办法在读卡器中等待下一行,或者在无限循环中重复当前行的步骤? 我正在使用Java配置,因此我的代码是: @Bean public Job importUserJob() { Job job = jobBuilders.get("importUserJob").incrementer(new Ru

我正在用SpringBatch处理一个平面文件,但我有一个问题——有时我必须等待文件中的流——因为文件是通过网络写入的。现在,当
FlatFileReader
读取空行时,步骤的退出状态已完成。有没有办法在读卡器中等待下一行,或者在无限循环中重复当前行的步骤? 我正在使用Java配置,因此我的代码是:

@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中读取

若读取行为null或等待行,可能是重试步骤的另一种方法??
可能问题是我正在使用内置于hsqldb的内存???

解决方案是在第一步下载文件,然后在第二步处理它。

这是最好的,因为您可以重新启动/继续处理,而无需再次下载文件,并且不会遇到超时/重试问题。

FlatFileItemReader希望文件在开始处理之前已完全写入。如果文件仍在编写中,则应等到文件完成后再开始作业。

我通过以下方式解决了问题: 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;
    
    }

  • 然后在我的工作构建器中:

    Job job = jobBuilders.get("importUserJob").incrementer(new RunIdIncrementer()).flow(step1()).next(waitStep()).next(step1()).end().build();
    

    这正是我想要的。现在我的step1正在运行,当我的流结束时,waitStep正在运行(等待30秒),然后step1正在运行,但跳过前面读取的行。一遍又一遍;-)

    嗯,文件在同一个系统上,所以我不需要下载它,但问题是另一个服务正在写入此文件(有时不写入,然后我的步骤完成,状态已完成)。好的,我知道并同意你的意见,但你知道有什么方法可以这样做吗?我尝试使用FlatFileReader的自定义实现,并将方法
    readLine()
    重写为:
    line=this.reader.readLine();如果(line==null){wait(1000);返回readLine();
    但是Spring批处理抛出ExceptionException在java.lang.Thread.run(Thread.java:745)处抛出,原因是:java.lang.IllegalMonitorStateException:null在java.lang.Object.wait(本机方法)老实说,我会从Spring集成文件尾部功能中使用的与消息生成器相关的代码(
    OSDelegatingFileTailingMessageProducer
    ApacheCommonsFileTailingMessageProducer
    )开始,并将其包装在一个
    ItemReader
    中。困难的部分是如何判断何时完成(因为文件仍在写入中)。Michael谢谢。好吧,有两种方法可以做到这一点-我们可以建立读取的行数,在该计数限制之前等待流或建立该步骤永远不会结束。目前我不知道如何在无限循环中运行该步骤。也许你知道怎么做?我正在尝试使用
    公共步骤step1(){return stepBuilders.get(“step1”).allowstartificomplete(true).chunk(500).reader(reader()).processor(processor()).writer(mongoWriter()).build();
    但当步骤以完成状态结束时,它不会重新启动。