Java Jackson CSV解析器在逗号分隔的值文件上阻塞,如果&引用;在字段中,即使使用“引用”;

Java Jackson CSV解析器在逗号分隔的值文件上阻塞,如果&引用;在字段中,即使使用“引用”;,java,csv,jackson,Java,Csv,Jackson,守则: package org.javautil.salesdata; import java.io.File; import java.io.IOException; import java.util.Map; import org.javautil.util.ListOfNameValue; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.dataformat.csv.

守则:

package org.javautil.salesdata;
import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.javautil.util.ListOfNameValue;

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;

// https://github.com/FasterXML/jackson-dataformats-text/tree/master/csv
public class Manufacturers {
    private static final String fileName= "src/main/resources/pdssr/manufacturers.csv";

    ListOfNameValue getManufacturers() throws IOException {
        ListOfNameValue lnv = new ListOfNameValue();
        File csvFile = new File(fileName);
        CsvMapper mapper = new CsvMapper();

        CsvSchema schema = CsvSchema.emptySchema().withHeader(); // use first row as header; otherwise defaults are fine
        MappingIterator<Map<String,String>> it = mapper.readerFor(Map.class)
           .with(schema)
           .readValues(csvFile);
        while (it.hasNext()) {
          Map<String,String> rowAsMap = it.next();
          System.out.println(rowAsMap);
        }

        return lnv;

    }

}
例外是

fasterxml.jackson.databind.exc.RuntimeJsonMappingException:条目太多:最多应为3个(值#3(4个字符)“LLC”)


我原以为我会扔掉自己的CSV解析器,采用一个功能更强大的受支持项目,但大多数项目的速度要慢得多,只是简单的中断,或者网络上到处都有与当前版本的产品不兼容的示例。

问题是您的文件不符合CSV标准。第三个字段总是以空格开头>
mfr_id","mfr_cd","mfr_name"
"0000000020","F-L", "Frito-Lay"
"0000000030","GM", "General Mills"
"0000000040","HVEND", "Hershey Vending"
"0000000050","HFUND", "Hershey Fund Raising"
发件人:

根据RFC 4180的规定,
字段中引号外的空格是不允许的
;但是,RFC还说“空格被视为字段的一部分,不应被忽略。”并且“在处理CSV文件时,实施者应该‘在你做的事情上保守,在你接受他人的事情上自由’(RFC 793,第2.10节)

Jackson在处理你的大部分记录时是“自由的”;但是当它发现

"0000000160","CADBURY", "Cadbury Adam USA, LLC"
它别无选择,只能将is视为4个字段:

  • “0000000160”
  • “吉百利”
  • “吉百利亚当美国”
  • “有限责任公司”
建议修复该文件,因为这将允许使用大多数CSV库进行解析。您可以尝试其他库,它们并不短缺。

可以处理这些问题。它是为处理各种棘手的非标准CSV文件而构建的,并且比您正在使用的解析程序更快

请尝试以下代码:

    String fileName= "src/main/resources/pdssr/manufacturers.csv";
    CsvParserSettings settings = new CsvParserSettings();
    settings.setHeaderExtractionEnabled(true);

    CsvParser parser = new CsvParser(settings);
    for(Record record : parser.iterateRecords(new File(fileName))){
        Map<String, String> rowAsMap = record.toFieldMap();
        System.out.println(rowAsMap);
    }
String fileName=“src/main/resources/pdssr/manufacturers.csv”;
CsvParserSettings=新CsvParserSettings();
设置。setHeaderExtractionEnabled(真);
CsvParser parser=新的CsvParser(设置);
for(记录:parser.iteratereRecords(新文件(文件名))){
Map rowAsMap=record.toFieldMap();
System.out.println(rowAsMap);
}
希望这有帮助


披露:我是这个库的作者。它是开源和免费的(Apache 2.0许可证)

在第二个逗号之后和“;那可能是问题的根源。i、 e.第三个字段是
'“吉百利Adam USA'
不,它只发生在字段中带有逗号的记录上,您描述的情况是在正确处理的几个之前的记录中。我要说的是,该文件不符合CSV标准。空间在CSV中很重要。第三个字段以空格-->开头,因此该字段不包含在引号中。第三个字段行1的值应为“Frito-Lay”,即包括wikipedia中的引号:根据RFC 4180,字段中引号外的
空格是不允许的
;然而,RFC还表示,“空间被视为一个字段的一部分,不应被忽略。”以及“在处理CSV文件时,实施者应该‘在你所做的事情上保守,在你接受他人的东西上自由’(RFC 793,第2.10节)。是的,文件格式不正确。我更改了我的阅读器以引发异常。没有CSV标准。RFC 4180是一个标准提案。无论如何,试着说服外部各方以你想要的格式提供一个CSV文件,看看你能走多远(剧透警报:不远)。在处理CSV周围的各种角落案例方面做得很好,而且速度更快。如果您当前的解析器对您没有帮助,请尝试使用该方法。
    String fileName= "src/main/resources/pdssr/manufacturers.csv";
    CsvParserSettings settings = new CsvParserSettings();
    settings.setHeaderExtractionEnabled(true);

    CsvParser parser = new CsvParser(settings);
    for(Record record : parser.iterateRecords(new File(fileName))){
        Map<String, String> rowAsMap = record.toFieldMap();
        System.out.println(rowAsMap);
    }