首页 > 解决方案 > 如何在java中比较两个大的CSV文件

问题描述

我需要比较两个大的 csv 文件并找出差异。

第一个 CSV 文件将如下所示:

c71f55b6c18248b8915d8a26
64b7d2d4eab74d7999a967c0
ceb792ad21054fe0a27ec410
95319566f9424c57ba2145f9
682a4fe26c154050b8f5c6f1
88e0209e2af74049ad9bf2bd
5c462b42763d41d7bb67029f
0ee74c227fc84e39a9ecc1da
66f7ab6f56374ba08d2fb92d
3ed793e35f9441b58562c9ba
baad81ac8ba54188afe63fb8
...

每行只有一个 id,总行数约为 5 百万。第二个 CSV 文件将类似于第一个,总行数为 3 百万。

我需要从第一个 csv 中删除第二个 csv 的 id 并将它们放入 MongoDb 中。当我将所有行放入内存然后比较两个 CSV 文件时,出现内存不足错误。我有 512Mb 的内存空间,每天至少会收到 30 个请求。CSV 的行数正在变化 100 万至 1000 万。我可以同时收到两个请求并同时做同样的事情。

有没有其他办法呢?

谢谢。

标签: javacsvfile

解决方案


如果您需要在 java 中管理数据,您可以使用Set基本数据结构来保存数据:

不包含重复元素的集合

特别是在您的情况下,最好使用HashSet字符串,因为:

此类为基本操作(添加、删除、包含和大小)提供恒定的时间性能

这意味着从 an 添加和删除项目HashSet不依赖于HashSet. 保存 10.000.000 或 24 个字符的字符串可以用大约半 GB 的 ram 完成,因此您可以将所有内容保存在内存中,但是如果您受到半 GB 内存的限制,请考虑 10.000.000 是您的上限。

代码可以是

Set<String> items = new HashSet<>();

...
// For each item in the first file (may be a loop or stream)
items.add(item);
...
// For each item in the second file (may be a loop or stream)
items.remove(item);
...
// Here the set contains all items of the first csv without items present also 
// in the second csv

推荐阅读