【问题标题】:File diff of large size files大尺寸文件的文件差异
【发布时间】:2016-11-21 07:08:05
【问题描述】:

我需要用 java 编写这个任务。 我有 2 个大约 5GB 的大文件,每个文件都包含多行的文本数据。每行是一行以逗号分隔的字段,例如“name,empId,designation,address,...,so on up to 30 fields”。我需要读取这两个文件并将记录写入另一个文件,其中包含指定给定数据行已更改、未更改、添加或删除的附加字段。 例如

文件1

汤姆,E100,工程师

瑞克,E200,工程师

文件2

汤姆,E100,经理

保罗,E300,文员

结果文件

汤姆,E100,经理,改变

保罗,E300,文员,添加

Rick,E200,工程师,已删除

我使用的方法是使用 empId 作为键和整个数据行作为值(假设 empId 是唯一的)从 file1 的数据创建一个映射,然后从 file2 读取每条记录以检查映射中的数据(我我没有将 file2 的全部内容读入内存,而只是 file1 来创建地图)。我正在使用 BufferedReader/BufferedWriter 进行读写。

这种方法效果很好,但只适用于小数据文件。考虑到运行到 GB 的数据文件,我的程序在尝试创建地图时很快就会耗尽内存。

就内存和执行速度而言,完成此任务的正确方法是什么?

谢谢, LX

【问题讨论】:

  • 你能得到按empId排序的文件吗?比您不需要将任何文件存储在内存中。 (所以也许可以按 empId 对它们进行排序)。

标签: algorithm memory-management data-structures large-files large-data-volumes


【解决方案1】:

另一种方法是根据密钥对每个文件执行external sort,然后并行迭代它们。

高级伪代码:

sort(file1)
sort(file2)
iter1 = file1.begin()
iter2 = file2.begin()
while (iter1 != file1.end() && iter2 != file2.end()):
  element1 = iter1.getElement()
  element2 = iter2.getElement()
  if element1.key() == element2.key():
     // same element, check if changed
     iter1 = iter1.next()
     iter2 = iter2.next()
  else if element1.key() < element2.key()
     // element1 is not in file2, so it is removed.
     iter1 = iter1.next()
  else 
     // element2 is in file2 but not in file1, so it's added
     iter2 = iter2.next()

while (iter1 != list1.end()):
  element1 = iter1.getElement()
  // element1 is removed 
  iter1 = iter1.next()

while (iter2 != list2.end()):
  element2 = iter2.getElement()
  // element2 is added
  iter2 = iter2.next()

这需要排序,在进行外部排序时只需很少的内存签名即可完成,并且下一个循环也使用恒定量的内存。 复杂度是O(mlogm + nlogn),其中n,m 是列表大小

【讨论】:

  • 对于这种大小的文件来说,这几乎是唯一合理的选择。
猜你喜欢
  • 2013-07-18
  • 1970-01-01
  • 2018-10-26
  • 2011-08-18
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多