【问题标题】:How can I parse a csv in low memory, using some parser in Java?如何使用 Java 中的一些解析器解析低内存中的 csv?
【发布时间】:2017-09-13 10:11:54
【问题描述】:

我使用了 InputStream,并且在解析时,如果在一列中有 ",",那么它会将其视为单独的列。 前 - abc, xyz, "m,n" 那么解析后的输出是abc , xyz, m, n 这里 m 和 n 被视为单独的列。

【问题讨论】:

  • 也许java.io.StreamTokenizer 是一种可能性。或者像JFlex 这样的扫描仪生成器。不过,您必须知道如何为 CSV 文件的语法设置它们;它们不是“开箱即用”的解决方案。
  • 你的文件的数据结构是什么,解析后的结果应该怎么处理?程序可以消耗多少内存?
  • 解析 CSV 不需要太多内存。你需要的记忆是存储它。解决方法:不要。一次处理一行。

标签: java csv parsing inputstream memory-efficient


【解决方案1】:

有很多第三方的Csv解析库,比如

  1. UniVocity Parser

  2. CommonsCsv Parser

  3. OpenCsv Parser

  4. SuperCsv Parser

我正在使用 UniVocity csv 解析器,它速度非常快,可以自动检测行中的分隔符。您可以浏览上面给出的 csv 库。

【讨论】:

    【解决方案2】:

    我真的很喜欢 Apache Commons CSVParser。这几乎是他们用户指南中的逐字记录:

    Reader reader = new FileReader("input.csv");
    final CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT);
    try {
        for (final CSVRecord record : parser) {
            final String string = record.get("SomeColumn");
            ...
        }
    } finally {
        parser.close();
        reader.close();
    }
    

    这很简单,可配置且面向行。

    你可以这样配置:

    final CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader().withDelimiter(';'));
    

    作为记录,此配置是不必要的,因为 CSVFormat.DEFAULT 完全按照您想要的方式工作。

    这是我第一次尝试看看它是否适合记忆。如果不是,您能否更具体地说明低内存占用?

    【讨论】:

    • 感谢回复 CSVParser 将整个文件加载到内存中,这是一个问题。如果文件大小是 1GB,那么内存消耗已经是 1GB 左右。
    • @somey CSVParser 可以做到这两点:将所有内容读入内存,并明智地读取记录。见commons.apache.org/proper/commons-csv/apidocs/index.html
    • @somey 你如何解析它?那部分代码也可以将内容读入内存。你能告诉我们你是怎么做的吗?此外,您可以连接jvisualvm 并查看究竟是什么消耗了这么多内存。也许需要 gc 运行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 2010-12-29
    相关资源
    最近更新 更多