gpt4 book ai didi

java - 自定义 CSVFormat.RFC4180

转载 作者:行者123 更新时间:2023-12-02 11:16:43 31 4
gpt4 key购买 nike

我必须读取 csv 文件。该文件可以包含任何分隔符,并且可以用“”\”括起来,也可以不括起来。该文件还应该根据 RFC4180 进行解析。(我知道在 RFC4180 中分隔符是“,”,但用户也应该能够读取例如,由“|”分隔的文件)。

public List<List<String>> readFileAsListOfList(File file, String delimiter, String lineEnding, String enclosure) throws Exception {
if (!file.exists()) {
throw new Exception("File doesn't exist.");
}
if (!file.isFile()) {
throw new Exception("File must be a file.");
}

List<List<String>> fileContent = new ArrayList<>();
CSVFormat csvFormat = CSVFormat.RFC4180.withDelimiter(delimiter.charAt(0)).withEscape(lineEnding.charAt(0));
if (StringUtils.isNotEmpty(enclosure)) {
csvFormat.withQuote(enclosure.charAt(0));
} else {
csvFormat.withQuote(null);
}
System.out.println(csvFormat);
List<String> lineContent = new ArrayList<>();
for (CSVRecord rec : csvFormat.parse(new FileReader(file))) {
for (String field : rec) {
lineContent.add(field);
}
fileContent.add(lineContent);
}
return fileContent;
}

如果我现在遇到文件未包含在内的情况,并且我有一行像

aaa|bbb|"|ccc

我收到以下错误:

Exception in thread "main" java.lang.IllegalStateException: IOException reading next record: java.io.IOException: (startline 120707) EOF reached before encapsulated token finished at org.apache.commons.csv.CSVParser$1.getNextRecord(CSVParser.java:530) at org.apache.commons.csv.CSVParser$1.hasNext(CSVParser.java:540) at com.ids.dam.pim.validation.CSVFileReaderApache.readFileAsListOfList(CSVFileReaderApache.java:61) at com.ids.dam.pim.validation.CSVFileReaderApache.main(CSVFileReaderApache.java:78) Caused by: java.io.IOException: (startline 120707) EOF reached before encapsulated token finished at org.apache.commons.csv.Lexer.parseEncapsulatedToken(Lexer.java:288) at org.apache.commons.csv.Lexer.nextToken(Lexer.java:158) at org.apache.commons.csv.CSVParser.nextRecord(CSVParser.java:586) at org.apache.commons.csv.CSVParser$1.getNextRecord(CSVParser.java:527) ... 3 more

我认为这是因为我的 CSVFormat 仍然包含双引号作为附件,因为这是 RFC4180 中的默认设置。

打印出格式如下:

Delimiter=<|> Escape=<L> QuoteChar=<"> RecordSeparator=<
> SkipHeaderRecord:false

对我来说,这意味着我可以用 CSVFormat.RFC4180.withDelimiter(delimiter.charAt(0)... 覆盖默认分隔符但我无法将外壳设置为空

有没有办法在仍然使用 RFC4180 的同时将外壳设置为空?

最佳答案

在 CSV 中,引号始终是可选的,并且可以选择引号字符和分隔符。如果您知道您的文件使用 | 分隔符且没有引号,则应该以这种方式构建 CSVFormat。请注意,withOption(...) 不会将该选项应用于当前的 csv 格式,而是返回一个与原始格式相同但设置了选项的 now 格式。来自 Apache CSVFormat javadoc

public CSVFormat withQuoteMode(QuoteMode quoteModePolicy)

Returns a new CSVFormat with the output quote policy of the format set to the specified value.
...

Returns: A new CSVFormat that is equal to this but with the specified quote policy

您应该使用:

    CSVFormat csvFormat = CSVFormat.RFC4180.withDelimiter(delimiter.charAt(0))
.withEscape(lineEnding.charAt(0));
if (StringUtils.isNotEmpty(enclosure)) {
csvFormat = csvFormat.withQuote(enclosure.charAt(0));
} else {
csvFormat = csvFormat.withQuoteMode(NONE);
}

关于java - 自定义 CSVFormat.RFC4180,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50217170/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com