Невозможно проанализировать последний столбец из файла CSV с помощью Apache Commons CSV - PullRequest
0 голосов
/ 06 октября 2019

У меня есть файл CSV с 19 столбцами (последний столбец пуст). Я анализирую файл через Apache Commons CSV. Когда я выполняю:

System.out.println("csvRecord.toString() = " + csvRecord.toString());

, я получаю следующий вывод:

csvRecord.toString() = CSVRecord [comment=null, mapping={Amount=6, ID=2, UID=4, Address=5, Carrier=17, CPL=14, F=12, GC=13, PIT=9, PP=11, PCIT=10, PT=1, SPI=3, SPI1=8, ST=7, Status=16, SOI=0, TN=18, TP=15}, recordNumber=6, values=[FB, S13 Wood Carving, B07, AG, bis, FB, 44.8, PE, AG XXXXXXX47, UNKNOWN, 39.95, 1.6, 4.1, , -2.2068006148899633, -0.46425251802390777, COMPLETED, US]]

Как видите, последний столбец TN=18 (который фактически является столбцом 19 при подсчете от одного)включается в выходные данные метода toString() в разделе mapping (но не в разделе values).

Однако, когда я преобразовываю csvRecord в карту с помощью следующего кода:

Map<String, String> csvRecordMap = csvRecord.toMap();

Последний столбец больше не присутствует. И когда я выполняю:

if (csvRecordMap.containsKey("TN")) 

Возвращает false.

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

Как заставить парсер возвращать все столбцы -- либо с помощью метода toMap(), либо каким-либо образом извлекая его из csvRecord напрямую, поскольку он явно присутствует, как показано в методе toString()?

Спасибо!

1 Ответ

1 голос
/ 06 октября 2019

Просмотрите и добавьте пропущенные имена:

Map<String, String> map = csvRecord.toMap();
for (String name : csvParser.getHeaderNames())
    map.putIfAbsent(name, "");

Демо

CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader();
try (CSVParser csvParser = csvFormat.parse(Files.newBufferedReader(Paths.get("test.txt")))) {
    System.out.println(csvParser.getHeaderNames());
    for (CSVRecord csvRecord : csvParser) {
        System.out.println(csvRecord);
        System.out.println("  toMap(): " + csvRecord.toMap());

        Map<String, String> map = csvRecord.toMap();
        for (String name : csvParser.getHeaderNames())
            map.putIfAbsent(name, "");
        System.out.println("  fixed  : " + map);
    }
}

test.txt

A,B,C,D
1,2,3,4
1,2,3
1,2
1
1,
1,,
1,,,
,,,4,,,

Выход (с commons-csv-1.7.jar)

[A, B, C, D]
CSVRecord [comment='null', recordNumber=1, values=[1, 2, 3, 4]]
  toMap(): {A=1, B=2, C=3, D=4}
  fixed  : {A=1, B=2, C=3, D=4}
CSVRecord [comment='null', recordNumber=2, values=[1, 2, 3]]
  toMap(): {A=1, B=2, C=3}
  fixed  : {A=1, B=2, C=3, D=}
CSVRecord [comment='null', recordNumber=3, values=[1, 2]]
  toMap(): {A=1, B=2}
  fixed  : {A=1, B=2, C=, D=}
CSVRecord [comment='null', recordNumber=4, values=[1]]
  toMap(): {A=1}
  fixed  : {A=1, B=, C=, D=}
CSVRecord [comment='null', recordNumber=5, values=[1, ]]
  toMap(): {A=1, B=}
  fixed  : {A=1, B=, C=, D=}
CSVRecord [comment='null', recordNumber=6, values=[1, , ]]
  toMap(): {A=1, B=, C=}
  fixed  : {A=1, B=, C=, D=}
CSVRecord [comment='null', recordNumber=7, values=[1, , , ]]
  toMap(): {A=1, B=, C=, D=}
  fixed  : {A=1, B=, C=, D=}
CSVRecord [comment='null', recordNumber=8, values=[, , , 4, , , ]]
  toMap(): {A=, B=, C=, D=4}
  fixed  : {A=, B=, C=, D=4}
...