One of the files I am parsing consist of two parts that I need to logically split into two different beans. I have found that the MultiBeanListProcessor is a great way to do this. I used test example 14 as source for my code.
Given the following configuration:
public class Sample {
public static void main(String[] args) throws IOException {
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setDelimiter('|');
MultiBeanListProcessor processor = new MultiBeanListProcessor(Person.class, Address.class);
String[] headers = new String[7];
headers[0] = "id";
headers[1] = "firstName";
headers[2] = "lastName";
headers[3] = "city";
headers[4] = "streetName";
headers[5] = "houseNo";
headers[6] = "houseAdd";
String[] selectedFields = new String[5];
selectedFields[0] = "firstName";
selectedFields[1] = "lastName";
selectedFields[2] = "city";
selectedFields[3] = "streetName";
selectedFields[4] = "houseAdd";
parserSettings.setHeaders(headers);
parserSettings.selectFields(selectedFields);
parserSettings.setProcessor(processor);
parserSettings.setColumnReorderingEnabled(false);
CsvParser parser = new CsvParser(parserSettings);
parser.parse(new FileReader("src/main/resources/input.csv"));
List<Person> persons = processor.getBeans(Person.class);
List<Address> addresses = processor.getBeans(Address.class);
for (Person person : persons) {
System.out.println(person.getFirstName());
}
for (Address address : addresses) {
System.out.println(address.getCity());
}
}
}
This really works very nice.
Unfortunately, the input file is to large to load in memory and I need to iterate instead of parse all at once. In a previously asked question an answer was given how to iterate over each bean. I however did not manage to apply this logic/code to this use case.
How do I iterate over each bean when using the MultiBeanListProcessor?
Currently the only option you have is to use the MultiBeanProcessor
(instead of MultiBeanListProcessor
), which is abstract and requires you to provide an implementation to method:
public void beanProcessed(Class<?> beanType, Object beanInstance, C context){
// your code here
}
Every time a new instance of a bean is created, this method will be called and you can process the object instances as required. You can use the context
object to get information about which record originated the object instance if needed. A very simple implementation could be:
private Person person;
private Address address;
public void beanProcessed(Class<?> beanType, Object beanInstance, C context){
if(beanType == Person.class){
person = (Person) beanInstance;
}
if(beanType == Address.class){
address = (Address) beanInstance;
}
if(person != null && address != null){
//got all beans from a row, process them
process(person, address);
//clear up until you get the instances produced for the next record.
person = null;
address = null;
}
}
Hope this helps