标签: opencsv

在java中解析大型CSV文件的最快且有效的方法

我想尽可能快速高效地解析大型 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)

csv parsing opencsv java-8

5
推荐指数
1
解决办法
6170
查看次数

如何更改opencsv的默认分隔符?

首先,您好,对于初学者的问题感到抱歉,但我已经看到了文档和教程,但我无法让它在我的代码上运行。也许我犯了一个小错误,但我无法抓住它。

我在 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 文档时

知道如何修复它吗?(抱歉我的英语,我不是母语人士)。

java opencsv

5
推荐指数
1
解决办法
7900
查看次数

OpenCsv:我可以指定一次区域设置,而不是在每个 @CsvBindByName 中重复它吗?

我正在使用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(...) …

java locale number-formatting opencsv

5
推荐指数
0
解决办法
2479
查看次数

writeAll(ResultSet res,Boolean b)opencsv方法在数据周围添加双引号

当我使用此函数写入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

4
推荐指数
1
解决办法
1万
查看次数

带有一些引用元素和其他未引用元素的 opencsv 写入文件

有没有人有在 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

想法?

java opencsv

4
推荐指数
1
解决办法
2998
查看次数

Spock:从CSV文件中读取测试数据

我正在尝试编写一个优雅的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)

csv groovy unit-testing opencsv spock

4
推荐指数
1
解决办法
4265
查看次数

OpenCSV无法读取Jersey2创建的InputStream

我有以下代码:

    @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)

java jersey opencsv jersey-2.0

4
推荐指数
1
解决办法
1354
查看次数

写操作期间发生磁盘错误。(来自HRESULT的异常:0x8003001D(STG_E_WRITEFAULT))

我正在使用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)

我该怎么办才能解决此错误?

vb.net asp.net opencsv

4
推荐指数
1
解决办法
9783
查看次数

来自 CSV 的 Hive 表。引号中的行终止

我尝试从保存到 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 是不正确的。你知道如何解决它吗?谢谢大家。

hadoop hive opencsv

4
推荐指数
1
解决办法
6815
查看次数

使用 OpenCSV,如何使用 MappingStrategy 附加到现有 CSV?

使用 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 …

opencsv

4
推荐指数
1
解决办法
2903
查看次数