5

I have a large array of a bean that needs to be written to a CSV file. I am trying to use OpenCSV but all the examples I see on the web ask me to convert the bean (POJO) that I have to a string array. I don't want to do this since this would mean I will have to go through the million beans and convert each of those beans to String[] which would be a very memory-expensive process.

This is the piece of code I have right now for doing this:

private static void writeRowsToCsv(Path filePath, List<MyBean> rows)
        throws IOException {

    StringWriter writer = new StringWriter();
    CSVWriter csvWriter = new CSVWriter(writer, '#', '\'');
    ColumnPositionMappingStrategy mappingStrategy =
            new ColumnPositionMappingStrategy();
    mappingStrategy.setType(MyBean.class);
    List<String[]> rowsInStringArray = convertBeanToStringArray(rows)
    csvWriter.writeAll(rowsInStringArray);
}

Is there a way I can avoid the conversion to String[] and use the list of beans that I have to write to a CSV file?

6
  • Why would that be very memory-expensive? You call writeNext() in a loop, converting one bean at a time. Commented Apr 10, 2017 at 14:51
  • That would mean I am writing one row at a time. I have a millions of rows to be written, which would make it extremely slow. Commented Apr 10, 2017 at 14:52
  • What do you think writeAll() does? It iterates the list and writes them, one at a time. How else would it process the list? Commented Apr 10, 2017 at 14:52
  • I haven't investigated but I believe it writes a batch of rows at a time. Commented Apr 10, 2017 at 15:04
  • What batching? There is no batching. Stop trying to guess when you have no clue. writeAll() is nothing but a loop calling writeNext(). See source code. Commented Apr 10, 2017 at 15:09

2 Answers 2

7

Jobin, seriously, if you are using OpenCSV then use the BeanToCsv or the newer StatefulBeanToCsv. It will save your sanity.

private static void writeRowsToCsv(Path filePath, List<MyBean> rows)
        throws IOException {

    StringWriter writer = new StringWriter();
    ColumnPositionMappingStrategy mappingStrategy =
            new ColumnPositionMappingStrategy();
    mappingStrategy.setType(MyBean.class);

    StatefulBeanToCsvBuilder<MyBean> builder = new StatefulBeanToCsvBuilder(writer);
    StatefulBeanToCsv beanWriter = builder
              .withMappingStrategy(mappingStrategy)
              .withSeparator('#')
              .withQuotechar('\'')
              .build();

    beanWriter.write(rows);
}
Sign up to request clarification or add additional context in comments.

5 Comments

The constructor StatefulBeanToCsvBuilder(CSVWriter) does not exist.
ledlogic - you are absolutely correct. I corrected my code example above as the StatefulBeanToCsv creates a CSVWriter based on values passed in from the builder but it does not take a CSVWriter directly. Not exactly sure what I was thinking back in May but thank you for pointing that out because who knows how long that would have stayed there.
this is the easier way to do it.
In OpenCSV 5.7.0, there is a constructor StatefulBeanToCsvBuilder(ICSVWriter) and CSVWriter implements it via AbstractCSVWriter.
why are the filePath and rows parameters not referenced in this method?
1

You call writeNext() in a loop, converting one bean at a time. Not memory-expensive at all.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.