我需要在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
答案 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
为列表大小