【问题标题】:Count duplicates in huge text files collection计算大型文本文件集合中的重复项
【发布时间】:2016-05-10 05:32:26
【问题描述】:

我有这个文件夹集合:

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-6000 万个句子。一个文件适合内存。

我需要对句子全局唯一进行去重和计数,以便获得一个新的文件集合,其中行被计数:

count    ...unique sentence...

馆藏很大。

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

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

【问题讨论】:

  • 你为什么不试试hadoop?如果没有,您可以启动适当的多个线程来读取每个文件,并且每个线程都尽力计算它。
  • 您是否需要对所有文件和所有目录进行重复数据删除和计数?
  • 我们可以假设唯一的行将适合内存,还是需要以最终结果大于可用内存的方式完成?
  • 尝试fork加入java的java框架
  • 您能否发布一个输入和预期输出的小示例。目前尚不清楚您想要实现什么。

标签: java sorting text corpus


【解决方案1】:

您的意思是删除每个文件的重复行?还是在所有文件中?

无论如何,你不能读取整个文件,你需要逐行读取,否则会抛出内存异常。使用 BufferedReader(例如here),使用映射存储重复行的计数作为值的字符串,当您读取一行时,如果存在,则放入映射递增值。

读取文件后,将所有行及其计数写入新文件并释放内存。

更新 1

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

【讨论】:

  • 没错,我需要对所有文件进行重复数据删除。按照你描述的方式,我只会在一个文件中复制,那个文件适合内存。
猜你喜欢
  • 2016-03-08
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多