无法使用Apache Commons CSV从CSV文件解析最终列

时间:2019-10-06 06:10:35

标签: java csv apache-commons

我有一个包含19列的CSV文件(最后一列为空)。我正在通过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部分的toString()方法的输出中包含了最后一列mapping(实际上是从一开始计数时的第19列)(但不包含在values部分)。

但是,当我通过以下代码将csvRecord转换为地图时:

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

最后一列不再存在。当我执行时:

if (csvRecordMap.containsKey("TN")) 

它返回false。

根据我的测试,我注意到toMap()方法如果后面没有 non empty 列,则不会包含一个空列(即使该列实际上存在于CSV文件)。如果某列为空,但其后有非空列,则它将包含在toMap()方法的返回值中。

如何强制解析器返回所有列-通过toMap()方法还是通过某种方式直接从csvRecord中提取它,因为显然toString()方法中显示了它? / p>

谢谢!

1 个答案:

答案 0 :(得分:1)

浏览并添加缺少的名称:

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}