У меня есть такой простой CSV-файл:

SellerProductID;ProductTextLong
1000;"a ""good"" Product"

И это попытка прочитать его с помощью Apache CSV:

    try (Reader reader = new StringReader(content)) {
      CSVFormat format = CSVFormat.DEFAULT.withDelimiter(';').withHeader().withEscape('"').withQuote('"');
      CSVParser records = format.parse(reader);
      System.out.println(records.iterator().next());
    }

Это не работает из-за:

Exception in thread "main" java.lang.IllegalStateException: IOException reading next record: java.io.IOException: (startline 2) EOF reached before encapsulated token finished
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.getNextRecord(CSVParser.java:145)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.next(CSVParser.java:171)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.next(CSVParser.java:137)
Caused by: java.io.IOException: (startline 2) EOF reached before encapsulated token finished
    at org.apache.commons.csv.Lexer.parseEncapsulatedToken(Lexer.java:288)
    at org.apache.commons.csv.Lexer.nextToken(Lexer.java:158)
    at org.apache.commons.csv.CSVParser.nextRecord(CSVParser.java:674)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.getNextRecord(CSVParser.java:142)
    ... 3 more

Другие инструменты CSV (например, Google Таблицы) могут нормально загружать CSV.

Это работает, если я использую другую кавычку или escape-символ, но, к сожалению, CSV клиента установлен.

Как настроить Apache CSV, чтобы разрешить использование одного и того же символа escape и кавычки? Или есть способ изменить поток, чтобы заменить символы кавычек на лету (файлы огромны)?

0
Steffi S. 13 Янв 2021 в 14:32

2 ответа

Лучший ответ

Проверенный атрибут - это логический атрибут.

Из Википедии:

Затем встроенные символы двойных кавычек могут быть представлены парой последовательных двойных кавычек или префиксом двойной кавычки с помощью управляющего символа, такого как обратная косая черта.

Таким образом, в этом случае "" - это просто два символа кавычек рядом друг с другом, в то время как escape-символ - это другой символ, используемый для экранирования кавычек, разрывов строк или разделителей.

Это исправляет (обратите внимание, что withEscape() вызывается по-другому, но данные примера не показывают, что на самом деле представляет собой escape-символ):

try (Reader reader = new StringReader(content)) {
    CSVFormat format = CSVFormat.DEFAULT.withDelimiter(';').withHeader().withEscape('/').withQuote('"');
    CSVParser records = format.parse(reader);
    System.out.println(records.iterator().next());
}
0
Steffi S. 15 Янв 2021 в 08:26

Я изучил вашу проблему, эту статью и эту < вам может помочь сообщение href="/questions/12139406/nedopustimyj-simvol-mezhdu-inkapsulirovannym-tokenom-i-razdelitelem-v-biblioteke-apache-commons-csv">. Попробуйте использовать также с .withNullString("").

-2
Dharman 13 Янв 2021 в 12:13