Как записать bean-компонент в CSV с помощью OpenCSV без преобразования в String[]?

У меня есть большой массив bean-компонентов, которые необходимо записать в файл CSV. Я пытаюсь использовать OpenCSV, но все примеры, которые я вижу в Интернете, просят меня преобразовать bean-компонент (POJO), который у меня есть, в массив строк. Я не хочу этого делать, так как это будет означать, что мне придется пройти миллион bean-компонентов и преобразовать каждый из этих bean-компонентов в String[], что было бы очень затратным по памяти процессом.

Это фрагмент кода, который у меня есть прямо сейчас для этого:

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);
}

Есть ли способ избежать преобразования в String[] и использовать список bean-компонентов, которые я должен записать в файл CSV?


person jobin    schedule 10.04.2017    source источник
comment
Почему это будет очень дорого для памяти? Вы вызываете writeNext() в цикле, преобразуя один компонент за раз.   -  person Andreas    schedule 10.04.2017
comment
Это означало бы, что я пишу по одной строке за раз. У меня есть миллионы строк, которые нужно написать, что сделало бы это очень медленным.   -  person jobin    schedule 10.04.2017
comment
Как вы думаете, что делает writeAll()? Он перебирает список и записывает их по одному. Как еще он будет обрабатывать список?   -  person Andreas    schedule 10.04.2017
comment
Я не исследовал, но я считаю, что он записывает партию строк за раз.   -  person jobin    schedule 10.04.2017
comment
Какая дозировка? Пакетирования нет. Прекратите пытаться угадать, когда вы понятия не имеете. writeAll() — это не что иное, как цикл, вызывающий writeNext(). См. источник код.   -  person Andreas    schedule 10.04.2017
comment
Спасибо @Андреас. Это означает, что лучший выход здесь — вызвать writeNext() в цикле. Если вы можете написать это как ответ, я могу отметить его принятым.   -  person jobin    schedule 10.04.2017


Ответы (2)


Вы вызываете writeNext() в цикле, преобразуя один компонент за раз. Совсем не дорого для памяти.

person Andreas    schedule 10.04.2017

Джобин, серьезно, если вы используете OpenCSV, используйте BeanToCsv или более новый StatefulBeanToCsv. Это спасет ваше здравомыслие.

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);
}
person Scott Conway    schedule 08.05.2017
comment
Конструктор StatefulBeanToCsvBuilder(CSVWriter) не существует. - person ledlogic; 25.10.2017
comment
ledlogic - вы абсолютно правы. Я исправил приведенный выше пример кода, так как StatefulBeanToCsv создает CSVWriter на основе значений, переданных из компоновщика, но не использует CSVWriter напрямую. Не совсем уверен, о чем я думал еще в мае, но спасибо, что указали на это, потому что кто знает, как долго это оставалось бы там. - person Scott Conway; 25.10.2017
comment
это самый простой способ сделать это. - person Bharath; 31.10.2017