大文件的文件差异

时间:2016-07-18 15:33:13

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

我需要在java中编写这个任务。 我有2个大约5GB的大文件,每个文件包含多行的文本数据。每行是一行逗号分隔的字段,例如" name,empId,names,address,...,最多30个字段"。我需要读取这两个文件并将记录写入另一个带有附加字段的文件,该字段指定给定的数据行是已更改,未更改,已添加或已删除。 例如

File1中

汤姆,E100,工程师

瑞克,E200,工程师

文件2

汤姆,E100,管理器

保罗,E300,办事员

ResultFile

汤姆,E100,管理器,改

保罗,E300,秘书,添加

瑞克,E200,工程师,已删除

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

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

在内存和执行速度方面,实现此任务的正确方法是什么?

谢谢, LX

1 个答案:

答案 0 :(得分: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为列表大小