Reputation: 71
I'm implementing Multi-Line Records Reader solution based on https://docs.spring.io/spring-batch/reference/html/patterns.html#multiLineRecords
I have the following flat file:
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(and optionally NCU, BAD) must be converted to a single object.
However in my case I don't have "end" line, so "HEA" is a start of new Item and end of previous one at the same time.
Thanks to Dean Clark for the good suggestion below. This is java config of the solution:
@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;
}
Then in the custom MultiLineCaseItemReader
your can do both read()
and peek()
Upvotes: 4
Views: 4342
Reputation: 3878
As the reference docs mention, you should create a custom implementation of ItemReader
to wrap the FlatFileItemReader
.
More specifically, you may want to extend SingleItemPeekableItemReader
and use FlatFileItemReader
as your delegate.
You'd peek()
ahead to the next item. If it's part of your current item
, great, go ahead and augment your item. If it's the next "header" line, then you've finished the item you're working and can return the current item
.
Then, the next read()
will start on the line you just peeked at without losing your place in the file or messing up restartability.
Upvotes: 10