多行记录 Reader(当开始前缀 = 结束前缀时)

Multi-Line Records Reader (when start prefix = end prefix)

我正在实施基于 https://docs.spring.io/spring-batch/reference/html/patterns.html#multiLineRecords

的多行记录 Reader 解决方案

我有以下平面文件:

HEA;0013100345;2007-02-15
NCU;Smith;Peter;;T;20014539;F
BAD;;Oak Street 31/A;;Small Town;00235;IL;US
HEA;0013100345;2007-02-15
NCU;Smith;Peter;;T;20014539;F
HEA;0013100345;2007-02-15

HEA(以及可选的 NCU、BAD)必须转换为单个对象。
但是在我的例子中,我没有 "end" 行,所以 "HEA" 是新项目的开始,同时也是前一个项目的结束。

感谢 Dean Clark 在下面提出的好的建议。这是解决方案的 java 配置:

@Bean
public FlatFileItemReader<FieldSet> readerFlat() {
    FlatFileItemReader<FieldSet> reader = new FlatFileItemReader<>();
    reader.setResource(new ClassPathResource("multirecord.txt"));
    reader.setLineMapper(compositeLineMapper());
    return reader;
}

@Bean
public SingleItemPeekableItemReader<FieldSet> readerPeek() {
    SingleItemPeekableItemReader<FieldSet> reader = new SingleItemPeekableItemReader<FieldSet>() {{
        setDelegate(readerFlat());
    }};
    return reader;
}

@Bean
public MultiLineCaseItemReader readerMultirecord() {
    MultiLineCaseItemReader multiReader = new MultiLineCaseItemReader() {{
        setDelegate(readerPeek());
    }};
    return multiReader;
}

然后在自定义 MultiLineCaseItemReader 中,您可以同时执行 read()peek()

如参考文档所述,您应该创建 ItemReader 的自定义实现来包装 FlatFileItemReader.

更具体地说,您可能想要扩展 SingleItemPeekableItemReader 并使用 FlatFileItemReader 作为您的委托。

您会 peek() 前进到下一个项目。如果它是您的 current item 的一部分,那太好了,继续增加您的项目。如果是下 "header" 行,那么您已经完成了正在处理的项目,可以 return current item.

然后,下一个 read() 将从您刚刚查看的行开始,而不会丢失您在文件中的位置或弄乱可重启性。