Чтение и запись CSV на Java с помощью Apache Commons CSV

Введение Это вторая статья из короткой серии, посвященной Библиотекам для чтения и записи CSV на Java [/ libraries-for-reading-and-writing-csvs-in-java], и прямое продолжение предыдущей статьи - Чтение и Написание CSV на Core Java [/ чтение-и-запись-csvs-in-java]. CSV Apache Commons Библиотека Apache Commons CSV [http://commons.apache.org/proper/commons-csv/download_csv.cgi] - это версия синтаксического анализатора Java CSV от Apache Software Foundation. По мнению пр

Вступление

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

CSV-файл Apache Commons

Библиотека CSV Apache Commons

  • это версия синтаксического анализатора Java CSV от Apache Software Foundation. Согласнорезюме проекта , он пытается « предоставить простой интерфейс для чтения и записи файлов CSV различных типов ».

Как и все библиотеки, связанные с Apache, он работает с лицензией Apache , что означает, что его можно свободно использовать, распространять и изменять.

Apache Commons позволяет разработчикам определять свои собственные форматы, но предлагает предопределенный набор форматов с помощью своего класса CSVFormat .

Эти предопределенные форматы:

  • RFC4180 - формат, разделенный запятыми, определенный в RFC 4180.
  • ПО УМОЛЧАНИЮ - аналогичен формату RFC4180, но допускает пустые строки между строками данных. Этот формат используется, если не указано иное, при определении синтаксического анализатора с помощью библиотеки CSV Apache Commons.
  • EXCEL - аналогичен RFC 4180, но допускает отсутствие имен столбцов и игнорирует пустые строки.
  • TDF - предопределенный формат для файлов CSV, разделенных табуляцией ( \t ) вместо запятых.
  • MYSQL - формат, поддерживаемый операциями SELECT INTO OUTFILE и LOAD DATA INFILE
  • ORACLE - формат CSV, используемый загрузчиком Oracle SQL.
  • INFORMIX_UNLOAD и INFORMIX_UNLOAD_CSV - специализированные форматы, определенные для использования с встраиваемой базой данных IBM Informix.
  • MONGODB_CSV и MONGODB_TSV - работает с базой данных Poplar NoSQL MongoDB для значений, разделенных запятыми и разделенными табуляцией, соответственно.
  • POSTGRESQL_CSV и POSTGRESQL_TEXT - формат, поддерживаемый базами данных PostgreSQL.

Если вам нужно очень простое решение, Apache Commons CSV может не подойти. Реализация разработана таким образом, чтобы обеспечить максимальную гибкость, поэтому исходный код составляет около 30 000 строк и в некоторых случаях оказывается довольно сложным для понимания.

Однако, если вам действительно нужно охватить широкий спектр форматов, Apache Commons - это надежная библиотека, хорошо поддерживаемая и регулярно обновляемая, с обширными документами Java и документацией для разработчиков для поддержки начинающих.

Он включен в репозиторий Maven Central и не имеет внешних зависимостей.

Чтение CSV с помощью Apache Commons CSV

Библиотека Apache Commons предлагает несколько методов для доступа к отдельным полям в файле CSV. Если вы работаете с такими приложениями, как Excel, ваш CSV в формате Excel, скорее всего, будет иметь заголовок.

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

Если ваш CSV-файл не содержит заголовка или вы не уверены, есть ли он в нем, вы можете использовать индекс для доступа к записи. Поскольку CSVRecord реализует интерфейс Java Iterable , индекс основан на 0, хотя индексы CSV при открытии в Excel и большинстве других приложений начинаются с 1:

 CSVParser csvParser = CSVFormat.DEFAULT.parse(new InputStreamReader(csvFile.getInputStream())); 
 for (CSVRecord record : csvParser) { 
 String field_1 = record.get(0); 
 String field_2 = record.get(1); 
 ... 
 } 

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

Давайте рассмотрим образец CSV-файла с данными дерева и назовем его «CSV данных дерева» для дальнейшего использования в этой статье:


[Индекс]{style=“font-weight:bold”} Обхват (в) Высота (футы) Объем (футы) 1 8,3 70 10,3


Чтобы ссылаться на каждую строку данных, мы могли бы использовать индексацию, как в предыдущем примере, или заголовок столбца:

 InputStreamReader input = new InputStreamReader(csvFile.getInputStream()); 
 CSVParser csvParser = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(input); 
 for (CSVRecord record : csvParser) { 
 String field_1 = record.get("Index"); 
 String field_2 = record.get("Girth (in)"); 
 String field_3 = record.get("Height (ft)"); 
 String field_4 = record.get("Volume (ft)"); 
 } 

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

Вместо использования .withFirstRecordAsHeader() при определении формата файла CSV вы можете определить заголовок вручную. Например, если вы не хотите ссылаться на единицы измерения в заголовке в нашем файле данных дерева, вы можете переопределить заголовок, чтобы использовать свои собственные строковые значения:

 CSVParser csvParser = CSVFormat.REF4180.withHeader("Index", "Girth", "Height", "Volume"); 
 for (CSVRecord record : csvParser) { 
 String field_2 = record.get("Girth"); 
 } 

Если ваш CSV-файл содержит заголовок, но вы хотите определить свой собственный заголовок и пропустить чтение заголовка в файле, используйте .readNext() чтобы пропустить первую строку:

 CSVRecord header = csvParser.readNext(); 
 // read the other rows in a loop as usual 

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

 public enum treeHeader { 
 Index, Girth, Height, Volume 
 } 
 ... 
 CSVParser csvParser = CSVFormat.DEFAULT.withHeader(treeHeader.class).parse(input); 
 // read rows 

В CSV-библиотеке Apache Commons есть несколько дополнительных методов, упрощающих синтаксический анализ, в том числе:

  • .getRecordNumber() - возвращает номер, присвоенный записи в CSV-файле.
  • .isConsistent() - может использоваться для обработки ошибок, возвращает True или False в зависимости от того, соответствует ли размер текущей записи размеру строки заголовка.
  • .size() - может использоваться для определения количества значений в записи.
  • .toString() - возвращает запись в виде строки. Полезно, когда вам нужно сохранить всю строку как строку для последующей обработки, хеширования или сравнения.

Написание CSV с помощью Apache Commons CSV

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

Однако есть некоторые полезные дополнительные функции, такие как возможность определять заголовок при печати и печать непосредственно из ResultSet JDBC ResultSet.

Класс CSVPrinter реализует Flushable и Closeable , делая его поведение похожим на расширение обычного Java Writer или StringWriter .

Например, чтобы сгенерировать CSV-файл с данными о дереве:

 CSVPrinter csvPrinter = new CSVPrinter(stringWriter, CSVFormat.DEFAULT.withHeader("Index", "Girth", "Height", "Volume")); 
 csvPrinter.printRecord("1", "8.3", "70", "10.3"); 
 csvPrinter.flush(); 

Метод .withHeader() принимает строковые значения заголовка в качестве параметров.

Если вы хотите создать CSV без заголовка, вы можете просто использовать new CSVPrinter(stringWriter, CSVFormat.DEFAULT); .

Если вы хотите использовать заголовки столбцов из существующего ResultSet JDBC ResultSet для печати, Apache Commons CSV принимает ResultSet в качестве параметра для своего .withHeader() :

 CSVPrinter csvPrinter = CSVFormat.RFC4180.withHeader(treeDataResultSet).print(out); 
 csvPrinter.printRecords(treeDataResultSet); 

Если используемый CSVFormat допускает пустые строки, вы можете использовать csvPrinter.println() для печати пустой строки между строками данных.

В дополнение к ResultSet , метод .printRecords() также может работать с Iterable Array или коллекцией строк, переданных методу с помощью varArgs .

Заключение

Apache Commons CSV пытается предоставить простой интерфейс для чтения и записи файлов CSV различных типов.

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

Однако, если вам действительно нужно охватить широкий спектр форматов, Apache Commons - это надежная библиотека, хорошо поддерживаемая и регулярно обновляемая, с обширными документами Java и документацией для разработчиков для поддержки начинающих.

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