1. Введение
В этом кратком руководстве мы познакомимся с OpenCSV 4, фантастической библиотекой для записи, чтения, сериализации, десериализации и/или анализа файлов .csv .
Затем мы рассмотрим несколько примеров, демонстрирующих, как настроить и использовать OpenCSV 4 для наших целей.
2. Настройка
Во-первых, мы добавим OpenCSV в наш проект с помощью зависимости pom.xml
:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.1</version>
</dependency>
.jars для OpenCSV
можно найти на официальном сайте или с помощью быстрого поиска в репозитории Maven .
Наш файл .csv
будет очень простым; мы сохраним его до двух столбцов и четырех строк:
colA, ColB
A, B
C, D
G, G
G, F
3. Быть или не быть фасолью
После добавления OpenCSV в наш pom.xml
мы можем реализовать методы обработки CSV двумя удобными способами:
- используя удобные
объекты CSVReader
иCSVWriter
(для более простых операций) - использование
CsvToBean
для преобразования файлов.csv
в bean-компоненты (которые реализованы как аннотированныеобычные-старые-java-объекты
)
В этой статье мы остановимся на синхронных
(или блокирующих ) примерах, чтобы сосредоточиться на основах.
Помните, что синхронный
метод предотвратит выполнение окружающего или последующего кода до тех пор, пока он не будет выполнен. В рабочих средах, скорее всего, будут использоваться асинхронные
(или неблокирующие
) методы, которые позволят другим процессам или методам завершиться, пока завершается асинхронный
метод.
Мы рассмотрим асинхронные
примеры для OpenCSV в следующей статье.
3.1. CSVReader
_ ``
Давайте изучим CSVReader
с помощью предоставленных методов readAll()
и readNext()
. Мы рассмотрим, как использовать readAll
() синхронно:
public List<String[]> readAll(Reader reader) throws Exception {
CSVReader csvReader = new CSVReader(reader);
List<String[]> list = new ArrayList<>();
list = csvReader.readAll();
reader.close();
csvReader.close();
return list;
}
Затем мы можем вызвать этот метод, передав BufferedReader
:
public String readAllExample() throws Exception {
Reader reader = Files.newBufferedReader(Paths.get(
ClassLoader.getSystemResource("csv/twoColumn.csv").toURI()));
return CsvReaderExamples.readAll(reader).toString();
}
Точно так же мы можем абстрагироваться от функции readNext
(), которая считывает предоставленный .csv
построчно:
public List<String[]> oneByOne(Reader reader) throws Exception {
List<String[]> list = new ArrayList<>();
CSVReader csvReader = new CSVReader(reader);
String[] line;
while ((line = csvReader.readNext()) != null) {
list.add(line);
}
reader.close();
csvReader.close();
return list;
}
Наконец, мы можем вызвать этот метод здесь, передав BufferReader:
public String oneByOneExample() throws Exception {
Reader reader = Files.newBufferedReader(Paths.get(
ClassLoader.getSystemResource("csv/twoColumn.csv").toURI()));
return CsvReaderExamples.oneByOne(reader).toString();
}
В качестве альтернативы, для большей гибкости и возможностей настройки, мы можем использовать CSVReaderBuilder
:
CSVParser parser = new CSVParserBuilder()
.withSeparator(',')
.withIgnoreQuotations(true)
.build();
CSVReader csvReader = new CSVReaderBuilder(reader)
.withSkipLines(0)
.withCSVParser(parser)
.build();
CSVReaderBuilder
позволяет нам пропускать заголовки столбцов и задавать правила парсинга через CSVParserBuilder
.
Используя CSVParserBuilder
, мы можем выбрать собственный разделитель столбцов, игнорировать или обрабатывать кавычки, указать, как мы будем обрабатывать пустые поля и как мы будем интерпретировать экранированные символы. Для получения дополнительной информации об этих параметрах конфигурации обратитесь к официальной документации спецификации .
Как всегда, нам нужно не забыть закрыть все наши программы чтения
, чтобы предотвратить утечку памяти.
3.2. CSVWriter
_ ``
Аналогичным образом CSVWriter
предоставляет возможность записи в файл .csv
сразу или построчно.
Давайте посмотрим, как писать в .csv
построчно:
public String csvWriterOneByOne(List<String[]> stringArray, Path path) throws Exception {
CSVWriter writer = new CSVWriter(new FileWriter(path.toString()));
for (String[] array : stringArray) {
writer.writeNext(array);
}
writer.close();
return Helpers.readFile(path);
}
Затем мы укажем, где мы хотим сохранить этот файл, и вызовем метод, который мы только что написали:
public String csvWriterSyncOneByOne() throws Exception{
Path path = Paths.get(
ClassLoader.getSystemResource("csv/writtenOneByOne.csv").toURI());
return CsvWriterExamples.csvWriterOneByOne(Helpers.fourColumnCsvString(), path);
}
Мы также можем написать наш .csv
сразу, передав массивы List
of String
, представляющие строки нашего .csv:
public String csvWriterAll(List<String[]> stringArray, Path path) throws Exception {
CSVWriter writer = new CSVWriter(new FileWriter(path.toString()));
writer.writeAll(stringArray);
writer.close();
return Helpers.readFile(path);
}
Наконец, вот как мы это называем:
public String csvWriterSyncAll() throws Exception {
Path path = Paths.get(
ClassLoader.getSystemResource("csv/writtenAll.csv").toURI());
return CsvWriterExamples.csvWriterAll(Helpers.fourColumnCsvString(), path);
}
3.3. Чтение на основе компонентов
OpenCSV может сериализовать файлы .csv в предустановленные и повторно используемые схемы, реализованные в виде аннотированных Java-компонентов
pojo
. CsvToBean создается
с использованием CsvToBeanBuilder
. Начиная с OpenCSV 4, CsvToBeanBuilder
является рекомендуемым способом работы с com.opencsv.bean.CsvToBean.
Вот простой bean-компонент, который мы можем использовать для сериализации нашего двухколоночного .csv
из раздела 2. :
public class SimplePositionBean {
@CsvBindByPosition(position = 0)
private String exampleColOne;
@CsvBindByPosition(position = 1)
private String exampleColTwo;
// getters and setters
}
Каждый столбец в файле .csv
связан с полем в bean-компоненте. Мы можем выполнять сопоставления между заголовками столбцов .csv , используя аннотации
@CsvBindByPosition
или @CsvBindByName
, которые определяют сопоставление по положению или совпадению строки заголовка соответственно.
Во-первых, мы создадим суперкласс с именем CsvBean, который позволит нам повторно использовать и обобщать методы, которые мы создадим ниже:
public class CsvBean { }
Вот пример дочернего класса:
public class NamedColumnBean extends CsvBean {
@CsvBindByName(column = "name")
private String name;
@CsvBindByName
private int age;
// getters and setters
}
Далее мы абстрагируем синхронно возвращаемый список
с помощью CsvToBean
:
public List<CsvBean> beanBuilderExample(Path path, Class clazz) throws Exception {
CsvTransfer csvTransfer = new CsvTransfer();
ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy();
ms.setType(clazz);
Reader reader = Files.newBufferedReader(path);
CsvToBean cb = new CsvToBeanBuilder(reader)
.withType(clazz)
.withMappingStrategy(ms)
.build();
csvTransfer.setCsvList(cb.parse());
reader.close();
return csvTransfer.getCsvList();
}
Затем мы передаем наш компонент ( clazz
) и устанавливаем его как ColumnPositionMappingStrategy
. При этом мы связываем поля наших bean-компонентов с соответствующими столбцами наших строк .csv .
Мы можем вызвать это здесь, используя подкласс SimplePositionBean
CsvBean
, который мы написали выше:
public String simplePositionBeanExample() throws Exception {
Path path = Paths.get(
ClassLoader.getSystemResource("csv/twoColumn.csv").toURI());
return BeanExamples.beanBuilderExample(path, SimplePositionBean.class).toString();
}
Мы также можем вызвать его здесь, используя NamedColumnBean,
еще один подкласс CsvBean
:
public String namedColumnBeanExample() throws Exception {
Path path = Paths.get(
ClassLoader.getSystemResource("csv/namedColumn.csv").toURI());
return BeanExamples.beanBuilderExample(path, NamedColumnBean.class).toString();
}
3.4. Написание на основе компонентов
Наконец, давайте посмотрим, как использовать класс StatefulBeanToCsv для записи в файл
.csv
:
public String writeCsvFromBean(Path path) throws Exception {
Writer writer = new FileWriter(path.toString());
StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer)
.withSeparator(CSVWriter.DEFAULT_SEPARATOR)
.build();
List<CsvBean> list = new ArrayList<>();
list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd"));
list.add(new WriteExampleBean("Test2", "ipso", "facto"));
sbc.write(list);
writer.close();
return Helpers.readFile(path);
}
Здесь мы указываем, как мы будем разграничивать наши данные, которые предоставляются в виде списка
указанных объектов CsvBean
.
Затем мы можем вызвать наш метод writeCsvFromBean()
после передачи желаемого пути к выходному файлу:
public String writeCsvFromBeanExample() {
Path path = Paths.get(
ClassLoader.getSystemResource("csv/writtenBean.csv").toURI());
return BeanExamples.writeCsvFromBean(path);
}
4. Вывод
В этой краткой статье мы обсудили примеры синхронного кода для OpenCSV с использованием bean-компонентов, CSVReader
и CSVWriter
. Для получения дополнительной информации ознакомьтесь с официальной документацией здесь.
Как всегда, образцы кода доступны на GitHub .