我想尽可能快速高效地解析大型 CSV 文件。
目前,我正在使用 openCSV 库来解析我的 CSV 文件,但解析一个包含 10776 条记录和 24 个标题的 CSV 文件大约需要 10 秒,我想解析一个包含数百万条记录的 CSV 文件。
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>4.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我正在使用 openCSV 库使用下面的代码片段进行解析。
public List<?> convertStreamtoObject(InputStream inputStream, Class clazz) throws IOException {
HeaderColumnNameMappingStrategy ms = new HeaderColumnNameMappingStrategy();
ms.setType(clazz);
Reader reader = new InputStreamReader(inputStream);
CsvToBean cb = new CsvToBeanBuilder(reader)
.withType(clazz)
.withMappingStrategy(ms)
.withSkipLines(0)
.withSeparator('|')
.withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_SEPARATORS)
.withThrowExceptions(true)
.build();
List<?> parsedData = cb.parse();
inputStream.close();
reader.close();
return parsedData;
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找另一种方法的建议,以在更短的时间内解析包含数百万条记录的 CSV 文件。
---更新了答案----
Reader reader = new InputStreamReader(in);
CSVParser csvParser = new …Run Code Online (Sandbox Code Playgroud) 首先,您好,对于初学者的问题感到抱歉,但我已经看到了文档和教程,但我无法让它在我的代码上运行。也许我犯了一个小错误,但我无法抓住它。
我在 Maven 项目中使用最新版本的 opencsv。所以我需要制作一个 .csv 文件,为此我使用:
try (CSVWriter writer = new CSVWriter(new FileWriter("file.csv", true)) {
/* code
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但我需要使用不同的分隔符,所以我尝试使用:
try (CSVWriter writer = new CSVWriter(new FileWriter("file.csv", true), '-') {
/* code
}
Run Code Online (Sandbox Code Playgroud)
但在 IntelliJ 中出现无法解析构造函数 'CSVWriter(java.io.FileWriter, char)',当文档中显示opencsv 文档时
知道如何修复它吗?(抱歉我的英语,我不是母语人士)。
我正在使用OpenCSV来解析 csv 文件,这些文件在英国和德国运行时都需要工作。解析数字时,我们需要指定区域设置,以便 OpenCSV 知道哪个小数点分隔符(“.”表示英国,“,”表示德国)和千位分隔符(“,”表示英国,“.”表示德国)
执行此操作的一种选择是在每个@CsvBindByName实例上指定区域设置
public class MyRowBackingBean {
@CsvBindByName(column = "Quantity", locale = "en-GB")
@CsvNumber("#0.0#")
private BigDecimal quantity;
@CsvBindByName(column = "Amount", locale = "en-GB")
@CsvNumber("#0.0#")
private BigDecimal amount;
}
Run Code Online (Sandbox Code Playgroud)
我想避免为每个字段重复区域设置,因此我希望采用全局方式来执行此操作。
解析 csv 的代码如下所示:
char seperator = ';';
CSVParser parser = new CSVParserBuilder().withSeparator(separator).build();
MappingStrategy<R> mappingStrategy = new HeaderColumnNameMappingStrategy<>();
mappingStrategy.setType(MyRowBackingBean.class);
try (Reader reader = ...) {
CSVReader csvReader = new CSVReaderBuilder(reader).withCSVParser(csvParser).build();
CsvToBean<R> csvToBean = new CsvToBeanBuilder<R>(csvReader)
.withMappingStrategy(mappingStrategy)
.withFilter(...)
.build();
List<MyRowBackingBean> beans = csvToBean.parse()
...
}
Run Code Online (Sandbox Code Playgroud)
我查看了以下类,但找不到 setDefaultLocale(...) …
当我使用此函数写入csv文件时,所有数据都嵌入双引号中.
有没有办法写入没有双引号的csv文件?
CSVWriter writer = new CSVWriter(new FileWriter(table+".csv"), '\t');
writer.writeAll(rset, true);
writer.close();
Run Code Online (Sandbox Code Playgroud)
该文件包含表单中的数据
"EMPNO" "ENAME" "JOB" "MGR" "HIREDATE" "SAL" "COMM" "DEPTNO" "TAG" "LOOKUP"
"7369" "SMITH" "CLERK" "7902" "17-Dec-1980" "800" "2" "20" "E" "1"
"7499" "ALLEN" "SALESMAN" "7698" "20-Feb-1981" "1600" "2" "30" "E" "2"
"7521" "WARD" "SALESMAN" "7698" "22-Feb-1981" "1250" "2" "30" "E" "3"
"7566" "JONES" "MANAGER" "7839" "02-Apr-1981" "2975" "2" "20" "E" "2"
Run Code Online (Sandbox Code Playgroud) 有没有人有在 Java 中使用 opencsv 编写 csv 文件的经验,其中只有一些元素需要双引号?我要测试的所需输出是制作一个文件,该文件将读取:
1,"two",three
但是当我尝试以下代码时
writer = new CSVWriter(new FileWriter("yourfile.csv"), ',',CSVWriter.NO_QUOTE_CHARACTER);
String[] entries = {"1","\"two\"","three"};
writer.writeNext(entries);
writer.close();
Run Code Online (Sandbox Code Playgroud)
出现以下输出
1,""two"",three
想法?
我正在尝试编写一个优雅的Spock规范,该规范将从CSV文件中读取非常大的测试数据,而无需将所有数据加载到内存中.我正在寻找你的反馈,你可能会比我现在拥有的更好.
我们假设我的简化CSV文件如下所示: -
1,2
3,4
5,6
Run Code Online (Sandbox Code Playgroud)
断言是 "column 1" + 1 == "column 2"
我正在使用OpenCSV来进行我的CSV解析,因为实际的CSV文件包含带有双引号和逗号等特殊字符的字符串,以及通过用逗号分割字符串的基本解析,这样就不起作用了.
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
尝试1
我的第一次尝试是遍历CSV并在每一行上执行断言.虽然这种方法有效,但我无法@Unroll将每个断言隔离到单独的独立测试中.
def "read from csv"() {
expect:
def reader = new CSVReader(...)
def fields
while ((fields = reader.readNext()) != null) {
def firstNum = Integer.valueOf(fields[0])
def secondNum = Integer.valueOf(fields[1])
firstNum + 1 == secondNum
}
}
Run Code Online (Sandbox Code Playgroud)
尝试2
这种尝试允许我使用,@Unroll但这需要将整个数据加载到内存中,这是我首先想要避免的.
@Unroll
def "read from csv"() {
expect:
Integer.valueOf(firstNum as String) + 1 == Integer.valueOf(secondNum as String)
where: …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
@POST
@Path("/csv")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String populateCSV(@FormDataParam("data") InputStream fileInputStream) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
File initialFile = new File("/Users/me/Downloads/file.csv");
InputStream targetStream = FileUtils.openInputStream(initialFile);
CSVReader reader = new CSVReader(new InputStreamReader(targetStream), ',', '"', 0);
CSVReader jerseyReader = new CSVReader(new InputStreamReader(fileInputStream), ',', '"', 0);
List<String[]> fileAllRows = reader.readAll();
List<String[]> jerseyAllRows = jerseyReader.readAll();
return null;
}
Run Code Online (Sandbox Code Playgroud)
jerseyAllRows从中CSVReader读取创建的文件将Jersey转换为InputStream返回空行,同时fileAllRows创建FileInputStream包含提交给jersey的同一文件的空行,返回3行.
是什么让Jersey2读取文件的方式创建了一个不同的InputStream?
我需要将文件发布到Jersey2并能够使用OpenCSV解析它
EDITED
如果我将泽西输入流转换为String,如下所示:
InputStream is = new ByteArrayInputStream(IOUtils.toString(inputStream).getBytes());
reader = new CSVReader(new InputStreamReader(is), ',', …Run Code Online (Sandbox Code Playgroud) 我正在使用EPPlus读取vb.net中的.csv文件。运行此代码时,出现错误“写操作期间发生磁盘错误。
(来自HRESULT的异常:0x8003001D(STG_E_WRITEFAULT))
这是我的代码:
Public Function ImportExcelSheet(ByVal filePath As String) As DataTable
Dim dtImportData As New DataTable()
Try
'If csv file have header then "true" else "false"
Dim hasHeader As Boolean = True
Using pck = New OfficeOpenXml.ExcelPackage()
Using stream = File.OpenRead(filePath)
pck.Load(stream)
End Using
Run Code Online (Sandbox Code Playgroud)
我该怎么办才能解决此错误?
我尝试从保存到 HDFS 的 CSV 文件创建表。问题是 csv在引号内包含换行符。CSV 中的记录示例:
ID,PR_ID,SUMMARY
2063,1184,"This is problem field because consists line break
This is not new record but it is part of text of third column
"
Run Code Online (Sandbox Code Playgroud)
我创建了蜂巢表:
CREATE TEMPORARY EXTERNAL TABLE hive_database.hive_table
(
ID STRING,
PR_ID STRING,
SUMMARY STRING
)
row format serde 'com.bizo.hive.serde.csv.CSVSerde'
with serdeproperties (
"separatorChar" = ",",
"quoteChar" = "\"",
"escapeChar" = "\""
)
stored as textfile
LOCATION '/path/to/hdfs/dir/csv'
tblproperties('skip.header.line.count'='1');
Run Code Online (Sandbox Code Playgroud)
然后我尝试计算行数(正确的结果应该是 1)
Select count(*) from hive_database.hive_table;
Run Code Online (Sandbox Code Playgroud)
但结果是 4 what 是不正确的。你知道如何解决它吗?谢谢大家。
使用 OpenCSV,如何使用 MappingStrategy 附加到现有 CSV?我可以找到很多不使用 Bean 映射策略的示例,但我喜欢使用 Bean 策略进行列映射的动态特性,并希望以这种方式工作。这是我的代码,它只是将单行重写为 CSV 文件而不是附加。
我怎样才能解决这个问题?使用 OpenCSV 4.5。注意:我将 FileWriter 设置为append=true。这种情况并没有按照我的预期进行。重新运行此方法只会导致用标题和单行覆盖整个文件。
public void addRowToCSV(PerfMetric rowData) {
File file = new File(PerfTestMetric.CSV_FILE_PATH);
try {
CSVWriter writer = new CSVWriter(new FileWriter(file, true));
CustomCSVMappingStrategy<PerfMetric> mappingStrategy
= new CustomCSVMappingStrategy<>();
mappingStrategy.setType(PerfMetric.class);
StatefulBeanToCsv<PerfMetric> beanToCsv
= new StatefulBeanToCsvBuilder<PerfMetric>(writer)
.withMappingStrategy(mappingStrategy)
.withSeparator(',')
.withApplyQuotesToAll(false)
.build();
try {
beanToCsv.write(rowData);
} catch (CsvDataTypeMismatchException e) {
e.printStackTrace();
} catch (CsvRequiredFieldEmptyException e) {
e.printStackTrace();
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
或者,通常的模式是将所有行加载到列表中,然后重写整个文件?我能够通过编写两个 MappingStrategy 映射策略,然后有条件地将它们与 if-file-exists …