我需要读取 csv 文件,但该文件包含断线。这是一个例子:
"name","address","link"
"7eleven","city, street, 1",https://somelink/1 \\the good line
Baby-Gym,"city, street, 2\",https://somelink/2 \\the broken line because it has \", sequence
在此示例中,CSV 文件的第二行已损坏,因为“address”的值包含
\",
序列。
我无法更改 CSV 文件。我只想阅读并忽略这些断线。但是,当 com.opencsv 库使用 csvReader.readNext() 读取超过一行(大约 5k 行)时,我遇到了意外行为。
这是我用来读取 CSV 文件的代码:
try (Reader reader = new BufferedReader(new InputStreamReader(is))) {
CSVParser parser = new CSVParserBuilder()
.withSeparator(',')
.withQuoteChar('"')
.build();
try (CSVReader csvReader= new CSVReaderBuilder(reader)
.withSkipLines(1)
.withCSVParser(parser)
.build()) {
Set<info> infoList = new HashSet<>();
String[] infoParts;
while ((infoParts = csvReader.readNext()) != null) {
// code
}
}
}
如何使用 OpenCSV 逐行读取,同时避免由于单条断线的存在而忽略 5k 行?
我无法在任何地方找到有关如何解决此问题的信息。 我尝试使用
new CSVReaderBuilder(reader).withMultilineLimit(1)
,但它只是抛出异常......
我查看了 CSVParser 和 CSVReader 文档,但没有找到必要的设置。请帮助我。
执行此操作的一种方法是将文件拆分为单独的
String
并单独解析每个。这意味着为每一行创建一个新的 CSVParser
,这可能会很昂贵——我还没有对这种方法进行基准测试:
package com.example.so;
import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvValidationException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class OpenCSVEg {
public static void main(String[] args) throws CsvValidationException, IOException {
String csv = "\"name\",\"address\",\"link\"\n" +
"\"7eleven\",\"city, street, 1\",https://somelink/1\n" +
"Baby-Gym,\"city, street, 2\\\",https://somelink/2\n" +
"\"7eleven2\",\"city, street, 3\",https://somelink/3\n";
try (BufferedReader reader = new BufferedReader(new StringReader(csv))) {
List<String> csvLines = reader.lines().toList();
List<String[]> items = csvLines.stream().skip(1).map(s -> {
// the parser has internal state, so we need a new one for each row
CSVParser parser = new CSVParserBuilder()
.withSeparator(',')
.withQuoteChar('"')
.build();
try (CSVReader csvReader = new CSVReaderBuilder(new StringReader(s))
.withCSVParser(parser)
.build()) {
return Optional.of(csvReader.readNext());
} catch (Exception e) {
return Optional.<String[]>empty();
}
}).flatMap(Optional::stream).collect(Collectors.toList());
System.out.println(items);
}
}
}