Чтение и запись CSV на Java с OpenCSV

Введение Это последняя статья из короткой серии, посвященной Библиотекам для чтения и записи CSV на Java [/ libraries-for-reading-and-writing-csvs-in-java], и является прямым продолжением предыдущей статьи - Чтение и Написание CSV на Java с помощью Apache Commons CSV [/ read-and-writing-csvs-in-java-with-apache-commons-csv]. OpenCSV OpenCSV [http://opencsv.sourceforge.net/] - один из самых простых и легких для понимания анализаторов CSV, использующий стандартные классы Reader / Writer и

Вступление

Это последняя статья в короткой серии, посвященной библиотекам для чтения и записи CSV на Java , и прямое продолжение предыдущей статьи - Чтение и запись CSV на Java с помощью Apache Commons CSV .

OpenCSV

OpenCSV - один из самых простых и легких для понимания парсеров CSV, использующий стандартные Reader / Writer и предлагающий CSVReader поверх.

Как и Apache Commons CSV, OpenCSV работает с лицензией Apache 2.0. Прежде чем загружать и решать, использовать ли парсеры OpenCSVs, вы можете просмотреть исходный код и документы Java и даже проверить их набор тестов JUnit, который включен в их репозиторий git.

OpenCSV также включен вMVNRepository , что упрощает управление зависимостями.

CSVReader позволяет получать одну запись за раз, несколько записей в виде списка или итератора, что делает его гибким с точки зрения удобства использования считываемых данных. Библиотека также включает в себя удобные функции, такие как чтение, запись в компоненты и из компонентов, а также прямое отображение из CSV в карту Java с использованием строки заголовка.

OpenCSV не имеет такого большого разнообразия предопределенных форматов, как Apache Commons CSV. Он полагается на два парсера:

  • CSVParser - исходный синтаксический анализатор, определенный в OpenCSV. Это работает для большинства простых экземпляров синтаксического анализа, но не работает, если есть escape-символы, определенные как часть самой записи.
  • RFC4180Parser - аналог CSVFormat.RFC4180 в Apache Commons CSV. Работает с CSV-файлами, отформатированными в соответствии со спецификациями RFC 4180. Эта версия анализатора рассматривает все символы между открывающими и закрывающими кавычками как содержимое, за исключением символа двойной кавычки, который необходимо экранировать другой двойной кавычкой.

Чтение CSV с OpenCSV

Чтение CSV с помощью OpenCSV происходит быстрее, чем с Apache Commons CSV, поскольку CSVWriter реализован как многопоточный при использовании CSVToBean.parse() .

CSVReader также реализован с использованием Java Iterable , поэтому можно управлять ограничениями памяти и времени в зависимости от выбранного вами метода реализации.

OpenCSV имеет два типа объектов для чтения CSV - CSVReader и его подкласс CSVReaderHeaderAware .

CSVReader похож на своего CSVParser Apache Commons и может использоваться как для простых, так и для сложных сценариев синтаксического анализа.

Чтобы перебрать каждую запись в файле CSV, где record будет массивом строк с разделенными запятыми значениями, разделенными на отдельные поля:

 CSVReader csvReader = new CSVReader (new InputStreamReader(csvFile.getInputStream())); 
 while ((record = csvReader.readNext()) != null) { 
 // do something 
 } 

Если ваш CSV разделен символом, отличным от запятой, вы можете вместо этого использовать конструктор с двумя параметрами и указать разделитель, который вы хотите использовать в CSVReader .

Например, если ваш CSV содержит значения, разделенные табуляцией, вы можете инициализировать CSVReader следующим образом:

 CSVReader csvReader = new CSVReader(new InputStreamReader(csvFile.getInputStream()), '\t'); 

OpenCSV также имеет более сложный способ синтаксического анализа файлов CSV, который включает в себя реализацию bean-компонентов для сопоставления полей в CSV, а затем использование аннотаций для определения типов записей с помощью аннотаций на основе заголовков или позиций.

Это помогает, поскольку позволяет обрабатывать записи CSV как общий набор данных, а не как набор отдельных полей.

Если имена заголовков обрабатываемого файла согласованы, вы можете аннотировать столбцы с @CSVBindByName аннотации @CSVBindByName и позволить OpenCSV позаботиться о сопоставлении и копировании стороны обработки проанализированных данных.

Например, с нашим древовидным набором данных:

 public class Trees { 
 @CSVBindByName 
 private int index; 
 
 @CSVBindByName 
 private int girth; 
 
 @CSVBindByName 
 private int height; 
 
 @CSVBindByName 
 private int volume; 
 
 public int getIndex() { 
 return this.index; 
 } 
 
 public void setIndex(int newIndex) { 
 this.index = newIndex; 
 } 
 ... 
 } 

Пока ваш файл CSV содержит заголовок, названный с именами переменных в нашем объявлении класса, OpenCSV может анализировать и считывать данные в соответствующий элемент с автоматическим преобразованием типов:

 List<Trees> treeParser = new CSVToBeanBuilder(FileReader("somefile.csv")).withType(Trees.class).build().parse(); 

При необходимости к методам получения и установки могут быть добавлены проверки, а обязательные поля могут быть указаны путем установки required в аннотации.

Если имя заголовка немного отличается от имени переменной, String также можно указать в аннотации. Возможность сопоставить имя заголовка, когда имя столбца отличается, полезна в нашем примере, поскольку наш фактический набор данных содержит единицу измерения поля, а также пробелы и знаки пунктуации, которые не допускаются в стандартных именах переменных Java.

В этом случае флаг и отображение могут быть указаны с аннотацией:

 ... 
 @CSVBindByName (column = "Girth (in)", required = true) 
 private int girth; 
 ... 

Если ваш CSV-файл не имеет заголовка, вы можете сопоставить его по положению столбца вместе с аннотацией @CSVBindByPosition

Имейте в виду, что позиции OpenCSV отсчитываются от 0:

 public class Trees{ 
 @CSVBindByPosition(position = 0, required = true) 
 private int index; 
 
 @CSVBindByPosition(position = 1, required = true) 
 private int girth; 
 
 @CSVBindByPosition(position = 2) 
 private int height; 
 
 @CSVBindByPosition(position = 3) 
 private int volume; 
 } 

Если вы хотите обрабатывать более сложные сценарии, вы можете реализовать класс с интерфейсом MappingStrategy и определить схему преобразования или сопоставления, которая соответствует вашему сценарию синтаксического анализа.

Написание CSV с OpenCSV

OpenCSV имеет больше возможностей, чем Apache Commons CSV, когда дело доходит до записи данных в файлы CSV. Это позволяет вам либо писать из массива строк, либо писать из списка объектов.

Запись из списка объектов требует, чтобы объекты были инициализированы и объявлены заранее. Итак, чтобы не усложнять задачу, давайте рассмотрим работу с массивом строк.

Чтобы создать файл CSV с данными из массива строк:

 CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv"), ','); 
 String[] records = "Index.Girth.Height.Volume".split("."); 
 csvWriter.writeNext(records); 
 csvWriter.close(); 

OpenCSV работает с концепцией, что CSV - это не просто значения, разделенные запятыми; он позволяет вам определить, какой разделитель вы хотите использовать в файле в качестве параметра в конструкторе CSVWriter

Точно так же при определении массива String вам может быть полезно объявить String, а затем разделить его на значения на основе разделителя. Это особенно полезно, когда вам нужно скопировать выбранное подмножество строк данных из одного CSV-файла или файла базы данных в другой.

При инициализации CSVWriter использование FileWriter или Writer является обязательным. Инициализация модуля записи с использованием только одного параметра приводит к созданию файла по умолчанию, разделенного запятыми.

Есть несколько дополнительных параметров для конкретных случаев использования:

  • Char separator - разделитель. Если не объявлено, разделителем по умолчанию будет запятая.
  • Char quotechar - символ кавычки. Это будет использоваться в том случае, если ваш набор данных содержит значение с запятой как часть набора данных, и вам нужно сгенерировать файл, разделенный запятыми. Обычно в качестве символов кавычек используются двойные кавычки, одинарные кавычки или косые черты.
  • Char escapechar - обычно используется для выхода из quotechar .
  • String lineend - строка или символ, определяющий конец строки данных.

Вы можете CSVWriter включая все необязательные параметры:

 CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv"), ",", "'","/", "\n"); 

CSVWriter также имеет несколько полей, которые вы можете передать конструктору в качестве параметров. Вы можете определить эти значения как константы и повторно использовать символы и строки в кодовой базе для сохранения согласованности.

Например, после объявления:

 CSVWriter.DEFAULT_SEPARATOR = ","; 
 CSVWriter.DEFAULT_QUOTE_CHARACTER = "'"; 
 CSVWriter.DEFAULT_ESCAPE_CHARACTER = "/"; 
 CSVWriter.DEFAULT_LINE_END = "\n"; 

Вы можете использовать:

 CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv"), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END); 

Или используйте OpenCSV, используя значения по умолчанию, если значения не определены явно в конструкторе, и просто вызовите:

 CSVWriter csvWriter = new CSVWriter(new FileWriter("new.csv")); 

Поэтому, если ваши данные включают строку с именем пользователя и адресом, например: JohnDoe, 19/2, ABC Street, Someplace , фактический формат строки, в котором вам нужно, чтобы это было "JohnDoe", "19 // Улица ABC, 2 /, Где-то " .

Заключение

OpenCSV - один из самых простых и легких для понимания парсеров CSV, использующий стандартные Reader / Writer и предлагающий CSVReader поверх.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus