在巨大的文本文件集合中计算重复项

时间:2016-05-10 05:32:27

标签: java sorting text corpus

我有这个文件夹集合:

60G ./big_folder_6
52G ./big_folder_8
61G ./big_folder_7
60G ./big_folder_4
58G ./big_folder_5
63G ./big_folder_2
54G ./big_folder_9
61G ./big_folder_3
39G ./big_folder_10
74G ./big_folder_1

每个文件夹包含100个txt文件,每行一个句子。例如,文件./big_folder_6/001.txt

sentence ..
sentence ..
... 

文件夹中的每个文件都在4到6 GB之间(从上面报告的总数中可以看出),或多或少有40-60万个句子。一个文件适合内存。

我需要对句子全局唯一进行重复数据删除和计数,以便获得计算行数的新文件集合:

count    ...unique sentence...

这个系列很大。

我的第一个实现(使用Java)是一种“合并排序”方法,在500个文件的新集合中排序行(使用前N个字符调度右侧文件中的每一行),然后在单个文件中排序和聚合重复项文件。

我知道这是一个wordcount map-reduce问题,但我宁愿避免它。问题是:我使用正确的方法来解决这类问题,还是应该考虑MapReduce旁边的其他工具/方法?

1 个答案:

答案 0 :(得分:-1)

你的意思是删除每个文件的重复行?或者在所有文件中?

在任何情况下,你都无法读取整个文件,你需要逐行读取或抛出内存异常。使用BufferedReader(例如here),使用存储字符串的映射,将重复行的计数作为值,当您读取一行时,如果存在则将值放入映射中。

读取文件后,将所有行和他们的计数写入新文件并释放内存。

更新1

问题是你有很多gigas。所以你不能在内存中保留每行,因为它可以抛出内存异常,但同时你必须将它们保存在内存中以快速验证它们是否重复。可能会想到的是,不是使用表示键值的字符串,而是放置字符串的哈希值(usgin string.toHash()),当它是第一个时,将其写入新文件,但每隔100行刷新一次或更多以减少写入磁盘的时间。在处理完所有文件并在文件中写入唯一行之后,地图中只有整数(字符串的哈希码作为键并计为值),您开始读取仅包含唯一行的文件,然后创建一个新的文件写入行和计数值。