在大型文本文件集合中计数重复项

pbpqsu0x  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(339)

我收集了以下文件夹:

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\u folder\u 6/001.txt:

sentence ..
sentence ..
...

文件夹中的每个文件的大小都在4到6gb之间(从上面报告的总数中可以看出),其中包含的句子或多或少有4000万到6000万句。一个文件可以放在内存中。
我需要进行重复数据消除并计算全局唯一的句子,以便获得一个新的文件集合,其中的行被计算:

count    ...unique sentence...

收藏量很大。
我的第一个实现(使用java)是一种“合并排序”方法,将500个文件的新集合中的行排序(使用前n个字符将正确文件中的每一行分派),然后对单个文件中的重复项排序和聚合。
我知道这是一个字数Map减少的问题,但我宁愿避免它。问题是:我是使用正确的方法来解决这类问题,还是应该考虑mapreduce之外的其他工具/方法?

ghhkc1vu

ghhkc1vu1#

你的意思是删除每个文件的重复行?还是在所有文件中?
在任何情况下,您都不能读取整个文件,您需要逐行读取,否则将引发内存异常。使用bufferedreader(这里的示例),使用一个Map来存储字符串,并将重复行的计数作为一个值,当您读取一行时,在Map中输入递增的值(如果存在)。
读取文件后,将所有行及其计数写入一个新文件并释放内存。
更新1
问题是你有很多千兆。因此您不能将每一行都保存在内存中,因为它可能引发内存异常,但同时您必须将它们保存在内存中,以便快速验证它们是否重复。may想到的不是一个代表键值的字符串,而是对字符串进行哈希处理(usgin string.tohash()),当它是第一个字符串时,将其写入新文件,但每100行或更多行刷新一次,以减少写入磁盘的时间。处理完所有文件并在文件中写入唯一行,并且Map中只有整数(字符串的hashcode作为键,count作为值),然后开始读取仅包含唯一行的文件,然后创建一个新文件来写入行和计数值。

相关问题