【问题标题】:Efficient way of processing large CSV file using java使用java处理大型CSV文件的有效方法
【发布时间】:2019-03-18 19:47:29
【问题描述】:

让我们考虑一个场景

  1. Accounts.csv
  2. Transaction.csv

我们将每个帐号映射到交易详情,因此一个帐号可以进行多笔交易。使用这些详细信息,我们必须为每个帐户生成 PDF

如果假设事务 CSV 文件非常大(>1 GB),那么加载所有详细信息和解析可能是内存问题。那么解析事务文件的最佳方法是什么?逐块读取也会导致内存消耗。请指教

【问题讨论】:

  • 我会将它们加载到数据库中,然后执行查询。
  • 1GB 不会被视为“非常大”的 IMO。对于相当大的堆,这根本不会有任何问题(特别是如果您逐块读取它)。将其加载到数据库中会浪费大量时间和资源。

标签: java csv


【解决方案1】:

正如其他人所说,数据库将是一个很好的解决方案。

或者,您可以对 帐号 上的 2 个文件进行排序。大多数操作系统都提供高效的文件分类程序,例如对于 linux(按第 5 列排序)

LC_ALL=C sort -t, -k5 file.csv > sorted.csv

取自Sorting csv file by 5th column using bash

你可以依次读取这两个文件

你的编程逻辑是:

if (Accounts.accountNumber < Transaction.accountNumber) {
    read Accounts file
} else if (Accounts.accountNumber = Transaction.accountNumber) {
    process transaction
    read Transaction file
} else {
    read Transaction file
}

内存要求很小,您只需要在内存中保存每个文件的一条记录

【讨论】:

    【解决方案2】:

    假设您使用 Oracle 作为数据库。 您可以使用 Oracle SQL Loader 工具将数据加载到相应的表中。

    加载数据后,您可以使用简单的 SQL 查询来连接和查询加载的表中的数据。

    这适用于所有类型的数据库,但您需要找到合适的工具来加载数据。

    【讨论】:

      【解决方案3】:

      当然,首先将数据导入数据库将是最优雅的方式。 除此之外,您的问题给人的印象是这不是一个选择。

      因此,我建议您逐行阅读 transactions.csv(例如使用 BufferedReader)。因为在 CSV 格式中,每一行都是一条记录,然后您可以(在阅读时)过滤掉并忘记每条不适合您当前帐户的记录。 一次文件遍历后,您拥有一个帐户的所有事务,并且通常应该适合内存。 这种方法的一个缺点是您最终会多次阅读交易,每个帐户 PDF 生成一次。但是,如果您的应用程序需要高度优化,我建议您已经使用过数据库。

      【讨论】:

        猜你喜欢
        • 2011-12-16
        • 2012-12-29
        • 2014-08-12
        • 2015-02-20
        • 1970-01-01
        • 2015-10-10
        • 2017-07-05
        • 2018-05-22
        相关资源
        最近更新 更多