如何比较非常大的CSV文件中的差异

6

我需要比较两个csv文件,每个文件大小在2-3 GB左右,在Windows平台下。我试过将第一个文件放进HashMap中,然后与第二个文件进行比较,但结果(预料之中)是非常高的内存消耗。

我的目标是获得另一个文件中的差异。

这些行可能以不同的顺序出现,有可能还会缺失。

有什么建议吗?


7
“compare”是什么意思?你只是想知道它们是否相同,还是像diff工具一样需要更详细的比较? - Eric Petroelje
1
更多细节会有所帮助。比如这些文件是否有序,因此您可以假定它们将具有相同行的运行(如果是这样,您可以并行迭代它们,显示类似于diff命令或任何其图形等效项的差异)。 - John Gaines Jr.
你有尝试过众多的“diff”工具吗? - Hot Licks
当然,由于您可以在Java中打开和读取文件,因此仅进行逐行比较并不难。您必须确定不匹配的策略,但根据预期的不匹配类型,这可能相当简单。 - Hot Licks
你说它们可以按不同的顺序排列,那么有没有一个字段可以唯一标识记录?如果没有,您只是想找到有多少条记录具有相同的值吗?报告的差异是否必须是特定于字段的,或者标记记录就足够了? - user845279
每个记录中都有一个唯一标识符。 - richarbernal
6个回答

4
假设您希望通过编程以Java的方式实现此操作,答案是不同的。
这两个文件都有序吗?如果是这样,那么您无需读取整个文件,只需从两个文件的开头开始:
1. 如果条目相匹配,请在两个文件中都将“当前”行向前移动。 2. 如果条目不匹配,请确定哪个文件的行会先出现,显示该行,并在该文件中将当前行向前移动。
如果您没有排序过的文件,则可以在进行差异比较之前对文件进行排序。同样,由于您需要一种低内存解决方案,不要将整个文件读入以进行排序。将文件切成可管理的块,然后对每个块进行排序。然后使用插入排序来合并块。

2
使用 uniVocity-parsers,它带有 Java 中最快的 CSV 解析器。您可以处理高达 100 GB 大小的文件而没有任何问题,并且处理速度非常快。
对于大型 CSV 文件的比较,建议使用自己实现的 RowProcessor 并将其包装在 ConcurrentRowProcessor 中。
声明:本库作者。该库是开源和免费的(Apache V2.0 许可证)。

当我点击 https://www.univocity.com/pages/parsers-tutorial 中的演示链接时,我收到了 421 错误请求。 - Sunil Nalluru

2

Unix命令diff可以用于查找精确匹配。

您也可以使用-b标志运行它,以忽略仅限于空格的差异。


抱歉,它只适用于Windows平台。 - richarbernal
Diff存在于Windows平台上,但需要安装它。您可以安装独立的可执行文件(标准GNU工具已经移植到Windows上),或者您可以安装Cygwin,它还提供了Bash shell和许多Unix兼容层。 - Edwin Buck
非常感谢@Edwin Buck,但我需要在Java下控制程序。 - richarbernal

1

有一个用于解析CSV文件的Java库OpenCSV。可以构建懒加载文件。请查看这篇文章。希望能帮到你。


1
我建议您逐行比较,而不是将整个文件上传到内存中。或者尝试只上传一组行。

0

这里有一个类似的Stack Overflow帖子,我在其中提供了一种解决方案的概述,该解决方案仅需要将两个文件中较小的一个存储在内存中:

如何比较两个大型CSV文件并获取差异文件

这是一般解决方案,不需要对文件进行排序,因为您在问题中声明行的顺序可能不同。

无论如何,即使可以避免。我不想在这里重复解决方案,但是思路是索引一个文件,然后遍历另一个文件。您可以通过仅保持哈希表和索引中每行的位置来避免在内存中存储整个较小的文件。以这种方式,您将不得不多次在磁盘上访问文件,但是您不必将其保存在内存中。

算法的运行时间为O(N + M)。内存消耗为O(min(N,M))。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接