CsvMalformedLineException:CSV 行末尾未终止的引用字段

Ziq*_*iqi 6 java opencsv

我正在编写代码来处理 tar.gz 文件列表,其中有多个 csv 文件。我遇到了下面的错误

com.opencsv.exceptions.CsvMalformedLineException: Unterminated quoted field at end of CSV line. Beginning of lost text: [,,,,,,
]
    at com.opencsv.CSVReader.primeNextRecord(CSVReader.java:245)
    at com.opencsv.CSVReader.flexibleRead(CSVReader.java:598)
    at com.opencsv.CSVReader.readNext(CSVReader.java:204)
    at uk.ac.shef.inf.analysis.Test.readAllLines(Test.java:64)
    at uk.ac.shef.inf.analysis.Test.main(Test.java:42)
Run Code Online (Sandbox Code Playgroud)

导致此问题的代码如下,B 行。

public class Test {
    public static void main(String[] args) {
        try {
            Path source = Paths.get("/home/xxxx/Work/data/amazon/labelled/small/Books_5.json.1.tar.gz");
            InputStream fi = Files.newInputStream(source);
            BufferedInputStream bi = new BufferedInputStream(fi);
            GzipCompressorInputStream gzi = new GzipCompressorInputStream(bi);
            TarArchiveInputStream ti = new TarArchiveInputStream(gzi);
            CSVParser parser = new CSVParserBuilder().withStrictQuotes(true)
                    .withQuoteChar('"').withSeparator(',').
                    .withEscapeChar('|').           // Line A
                     build();
            BufferedReader br = null;
            ArchiveEntry entry;
            entry = ti.getNextEntry();
            while (entry != null) {
                br = new BufferedReader(new InputStreamReader(ti)); // Read directly from tarInput
                System.out.format("\n%s\t\t  > %s", new Date(), entry.getName());
                try{
                    CSVReader reader = new CSVReaderBuilder(br).withCSVParser(parser)
                            .build();
                    List<String[]> r = readAllLines(reader);
                } catch (Exception ioe){
                    ioe.printStackTrace();
                }
                System.out.println(entry.getName());
                entry=ti.getNextEntry();        // Line B
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static List<String[]> readAllLines(CSVReader reader) {
        List<String[]> out = new ArrayList<>();
        int line=0;
        try{
            String[] lineInArray = reader.readNext();

            while(lineInArray!=null) {
                //System.out.println(Arrays.asList(lineInArray));
                out.add(lineInArray);
                line++;
                lineInArray=reader.readNext();
            }
        }catch (Exception e){
            System.out.println(line);
            e.printStackTrace();
        }
        System.out.println(out.size());
        return out;
    }
}
Run Code Online (Sandbox Code Playgroud)

我还附上了导致此问题的 csv 文件中实际行的屏幕截图,请查看第 5213 行。我还在此处包含一个测试 tar.gz 文件: https: //drive.google.com/file/d/1qHfWiJItnE19 -BFdbQ3s3Gek__VkoUqk/view?usp=共享

在此输入图像描述

在调试时,我有一些问题。

  • 我认为问题在于数据文件中的\字符(上面第5213行),它是Java中的转义字符。我通过将 A 行添加到上面的代码中验证了这个想法,并且它有效。但是,显然我不想对此进行硬编码,因为数据中可能有其他字符导致相同的问题。所以我的问题1是:有没有办法告诉Java忽略转义字符?类似于 的反义词withEscapeChar('|')更新:答案是使用“\0”,感谢下面的第一条评论。
  • 调试时,我注意到我的程序一旦遇到上述异常,就会停止处理 tar.gz 文件中的下一个 .csv 文件。为了解释我的意思,在上面链接中包含的 tar.gz 文件中,有两个 csv:_10.csv 和 _110.csv。有问题的行位于 _10.csv 中。当我的程序到达该行时,会引发异常,并且程序将继续处理下一个文件 _110.csv ( entry=ti.getNextEntry();)。readAllLines该文件实际上没问题,但应该读取下一个 csv 文件的方法将立即在第一行抛出相同的异常。我认为我的代码不正确,尤其是while循环:我怀疑输入流仍然停留在导致异常的先前位置。但我不知道如何解决这个问题。请帮助?

小智 3

使用RFC4180Parser对我有用。