微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解决这个错误,CSVFormat with double quote using apache commons?

如何解决如何解决这个错误,CSVFormat with double quote using apache commons?

我有一个无法解决错误,我使用 Apache Commons 读取我的 CSV 文件,但是有一行包含带双引号的字符串,它不是分隔符,它是字符串的一部分,我想要一种替代方法来摆脱应用程序给出的错误。这是代码错误

Reader in = Files.newBufferedReader(Paths.get(nomeArquivoCorretores),Charset.forName("ISO-8859-1"));      
Iterable<CSVRecord> records = CSVFormat
                    .newFormat(',')
                    .withQuote('"')
                    .withEscape('\\')
                    .withHeader(cabecalhoCorretores)
                    .withTrailingDelimiter()
                    .withQuoteMode(QuoteMode.ALL)
                    .parse(in);
for (CSVRecord record : records) {
                try { ... }

我在尝试浏览 csv 可迭代列表时遇到此类错误

java.lang.IllegalStateException:IOException 读取下一条记录:java.io.IOException:(第 1 行)封装令牌和分隔符之间的无效字符。

它理解为好像双引号是一个分隔符,但它是字符串的一部分并且正在破坏算法过程

解决方法

您输入的 CSV 无效。在第 2 节第 7 项中,RFC 4180 指出:

如果使用双引号将字段括起来,则出现在字段内的双引号必须通过在其前面加上另一个双引号来转义。

这里不是这样:

86954708000105,"LOPES "G" ADMC.CORRETORA DE SEGUROS LTDA",PJ,Suspenso,

应该是

86954708000105,"LOPES ""G"" ADMC.CORRETORA DE SEGUROS LTDA",

可能解决此问题的最佳方法是修复产生此无效 CSV 的程序

如果这是不可能的,您可以尝试解决它,但这将是一个脆弱的黑客。假设有问题的 CSV 生成器至少在错误方式上是一致的,并且不会在字段内将引号加倍,您可以首先将文件作为纯文本读取,然后尝试修复引号,然后将结果提供给实际的 CSV 阅读器。

import java.io.*;
import org.apache.commons.csv.*;

public class CsvHack {
    public static void main(String[] args) throws Exception {
        String csvdata = "86954708000105,\"LOPES \"G\" ADMC.CORRETORA DE SEGUROS LTDA\",";
        BufferedReader reader = new BufferedReader(new StringReader(csvdata));

        StringBuilder buffer = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            line = line.replaceAll("([^,])\"","$1\"\"");
            line = line.replaceAll("\",","\"\",");
            buffer.append(line);
            buffer.append("\r\n");
        }
        Reader hack = new StringReader(buffer.toString());

        Iterable<CSVRecord> records = CSVFormat
            .newFormat(',')
            .withQuote('"')
            .withEscape('\\')
            .withTrailingDelimiter()
            .withQuoteMode(QuoteMode.ALL)
            .parse(hack);
        for (CSVRecord record : records) {
            System.out.println(record.get(1));
        }
    }
}

这会将整个文件读入内存中的 StringBuilder(如果您正在处理大文件,这可能已经不行了),然后它使用正则表达式来替换不在后面或右边的引号在带两个引号的逗号之前。如果引用的文本中有逗号,这将中断;正则表达式是错误的工具。

另一种方法是实现您自己的 java.io.Reader 并将其放在文件和 CSV 解析器之间,然后在该阅读器的 read 方法中修复引号。

如果您得到有效引用的 CSV,这些方法会通过添加额外的引号将其弄乱。

同样,我强烈建议修复输出有缺陷 CSV 的程序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。