使用Apache Commons CSV阅读以下TSV代码段时:
Name DOB SIN Address, contact information
"Patience Middleton" "18-4-87" 720463771 "varius Cras sem aliquam taciti fames hendrerit tempor"
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
CSVFormat format = CSVFormat.newFormat('\t').withQuote('"');
CSVParser parsed = CSVParser.parse(csvData, format);
List<CSVRecord> record = parsed.getRecords();
System.out.println(parsed.getHeaderMap().toString());
Run Code Online (Sandbox Code Playgroud)
但是我总是得到一个NullPointerException说明parsed.getHeaderMap() == null.
根据API(https://commons.apache.org/proper/commons-csv/apidocs/org/apache/commons/csv/CSVParser.html),该方法可能会返回在列中迭代的标题映射的副本订购.
我的代码或CSV文件中有什么问题吗?图书馆失败了吗?
Apache CSV实现中是否有内置功能在读取csv时忽略标题大小写?
前段时间我们已经实现了将CSV导出文件转换为SQL的实用程序.为此,我们选择了Apache CSV.到目前为止,一切都很好,但现在我们已经有了变更请求.
我们处理的所有CSV文件都必须包含标题,现在我们应该以不区分大小写的方式读取这些标题,因此我们的用户不必花费精力在其中,并观察他们创建的CSV是否遵循我们的标题案例要求.
代码示例:
for (CSVRecord record : subsidiaryRows) {
String name = record.get(Data.NAME));
Run Code Online (Sandbox Code Playgroud)
Data.NAME的位置
public static final String NAME = "Name";
Run Code Online (Sandbox Code Playgroud)
当用户在其CSV中使用"name"作为列标题而不是使用大写"N"的"Name"时,问题显然会引发.
我已经跟踪了API和源代码,但找不到任何东西.有没有办法如何强制CSVRecord使用CaseInsensitiveMap进行映射或类似的东西?
我有一个37列CSV文件,我使用Apache Commons CSV 1.2在Java中解析.我的设置代码如下:
//initialize FileReader object
FileReader fileReader = new FileReader(file);
//intialize CSVFormat object
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING);
//initialize CSVParser object
CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);
//Get a list of CSV file records
List<CSVRecord> csvRecords = csvFileParser.getRecords();
// process accordingly
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我将要处理的CSV复制到我的目标目录并运行我的解析程序时,我收到以下错误:
Exception in thread "main" java.lang.IllegalArgumentException: Index for header 'Title' is 7 but CSVRecord only has 6 values!
at org.apache.commons.csv.CSVRecord.get(CSVRecord.java:110)
at launcher.QualysImport.createQualysRecords(Unknown Source)
at launcher.QualysImport.importQualysRecords(Unknown Source)
at launcher.Main.main(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
但是,如果我将文件复制到我的目标目录,打开并保存它,然后再次尝试该程序,它的工作原理.打开并保存CSV会添加最后所需的逗号,这样我的程序就无法获得没有足够的标题来阅读.
对于上下文,这里是保存之前/之后的示例行:
之前(失败):"数据","数据","数据","数据"
之后(工作):"数据","数据",,,"数据",,,"数据",,,,,,
所以我的问题是:为什么我打开并保存CSV格式会发生变化?我没有更改任何值或编码,保存时MS-DOS或常规.csv格式的行为是相同的.另外,我在我的测试中使用Excel来复制/打开/保存.
我需要使用一些编码或格式设置吗?我能以编程方式解决此问题吗?
提前致谢!
编辑#1:
对于其他上下文,当我第一次在原始文件中查看空行时,它只有新行^ …
我正在使用Commons CSV解析与电视节目有关的CSV内容。其中一个节目的节目名称带有双引号;
2010年9月10日116,6,2,29,“” JJ“(60分钟)”,“ http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj ”
节目名称为“ JJ”(60分钟),该名称已用双引号引起来。这在封装的令牌和定界符之间抛出IOException java.io.IOException:(第1行)无效的char。
ArrayList<String> allElements = new ArrayList<String>();
CSVFormat csvFormat = CSVFormat.DEFAULT;
CSVParser csvFileParser = new CSVParser(new StringReader(line), csvFormat);
List<CSVRecord> csvRecords = null;
csvRecords = csvFileParser.getRecords();
for (CSVRecord record : csvRecords) {
int length = record.size();
for (int x = 0; x < length; x++) {
allElements.add(record.get(x));
}
}
csvFileParser.close();
return allElements;
Run Code Online (Sandbox Code Playgroud)
CSVFormat.DEFAULT已设置withQuote('“')
我认为此CSV的格式不正确,应为““ JJ”“(60分钟)”“” JJ“(60分钟)”-但是有没有办法让通用CSV处理此问题,或者我需要手动修复此条目?
附加信息:其他显示名称在CSV条目中包含空格和逗号,并放在双引号中。
最初我有以下代码:
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
externalHttpCall(output.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
在这里我发现有时字节数组没有完全写入。
我知道这是因为在externalHttpCall调用过程中没有刷新流。
为了修复它,我写了以下内容:
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
printer.flush();
log.info("Printer was flushed");
externalHttpCall(output.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
它解决了这个问题,但在这里我迷失了一个想法,即仅在externalHttpCall. 所以我想出了以下解决方案:
externalHttpCall(convertToByteArray(items);
public byte[] convertToByteArray(List<MyBean> items){
try (var output = new …Run Code Online (Sandbox Code Playgroud) 我是 apache-commons-csv 1.6 的新手
我有一个基本要求,即打印 csv 文件,其中每条记录都换行。我正在尝试使用 CSVPrinter 的 println 方法。由于某些奇怪的原因,输出文件没有任何换行符。所有内容都打印在一行中。
我尝试在 Notepad++ 中打开输出并显示不可打印的字符。记录之间没有字符。任何帮助将不胜感激。谢谢。
CSVPrinter csvPrinter = null;
if(delimiter != null && delimiter.length() > 0) {
csvPrinter = new CSVPrinter(new FileWriter(outputFile), CSVFormat.newFormat(delimiter.charAt(0)).withHeader(header));
}else {
csvPrinter = new CSVPrinter(new FileWriter(outputFile), CSVFormat.DEFAULT.withHeader(header));
}
for(Map<String,String> record : inputList) {
List<String> valueList = new ArrayList<String>();
for(String key : record.keySet()) {
valueList.add(record.get(key));
}
System.out.println(valueList);
csvPrinter.printRecord(valueList);
csvPrinter.println();
}
csvPrinter.close();
Run Code Online (Sandbox Code Playgroud)
预期结果:
id|类型|值|键
4|excel|0|excel.sheet.no
5|excel|日/月/年|excel.日期.格式
6|excel|0|excel.baserate.rownum
实际结果: id|type|value|key4|excel|0|excel.sheet.no5|excel|dd/MM/yyyy|excel.date.format6|excel|0|excel.baserate.rownum
Apache Commons CSV项目非常适合解析逗号分隔值、制表符分隔数据和类似的数据格式。
我的印象是,该工具完全读取文件,并将生成的行对象保存在内存中。但我不确定,我找不到有关此行为的任何文档。
对于解析非常大的数据,我应该进行增量读取,一次一行,或者一次可能相对较少的行数,以避免压倒性的内存限制。
仅就内存使用方面而言,这里的想法就像 XML 的 SAX 解析器如何增量读取以最大限度地减少 RAM 的使用,而 DOM 样式的 XML 解析器则将文档完全读入内存以提供树遍历。
问题:
我有通常的带标题的 csv 文件
f1, f2, f3
1, 2, 3
Run Code Online (Sandbox Code Playgroud)
我尝试解析它:
Iterable<CSVRecord> records = CSVFormat.EXCEL.withIgnoreEmptyLines().withSkipHeaderRecord().parse(in);
records.forEach(record -> {
...
Run Code Online (Sandbox Code Playgroud)
但无论如何,第一条记录无论如何都是标题。
我有什么错吗?
我使用以下依赖项来读取 csv 文件:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.5</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
下面是我编写的用于读取 csv 文件的代码:
Reader reader = Files.newBufferedReader(Paths.get(file.getPath()));
CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
for(CSVRecord csvRecord: csvParser) {
System.out.println(csvRecord.get(0));
}
Run Code Online (Sandbox Code Playgroud)
我可以通过上述方法读取csv文件中的每一行。但是 csvParser.getRecords(); 返回空。我想要 CSV 文件中的总行数。我怎样才能做到这一点?
如何通过 Apache CSV 以 UTF-8 格式编写 CSV 文件?
我正在尝试通过以下代码生成 csv,其中 Files.newBufferedWriter() 默认将文本编码为 UTF-8,但是当我在 excel 中打开生成的文本时,会有无意义的字符。
我像这样创建 CSVPrinter:
CSVPrinter csvPrinter = new CSVPrinter(Files.newBufferedWriter(Paths.get(filePath)), CSVFormat.EXCEL);
Run Code Online (Sandbox Code Playgroud)
接下来我设置标题
csvPrinter.printRecord(headers);
Run Code Online (Sandbox Code Playgroud)
然后在循环中,我像这样将值打印到 writer
csvPrinter.printRecord("value1", "valu2", ...);
Run Code Online (Sandbox Code Playgroud)
我还尝试将文件上传到在线 CSV lint 验证器,它告诉我使用的是 ASCII-8BIT 而不是 UTF-8。我做错了什么?