我必须从极大的文本文件(100 Gb +)中删除重复的字符串
因为在内存中由于数据的大小,重复删除是没有希望的,所以我尝试过bloomfilter但是除了5000万字符串之外没有用。
总字符串类似于1万亿+
我想知道解决这个问题的方法是什么。
我最初的尝试是,将文件分成子文件数,对每个文件进行排序,然后将所有文件合并在一起......
如果你有更好的解决方案,请告诉我,
谢谢..
答案 0 :(得分:3)
您在这里寻找的关键概念是external sorting。您应该能够使用该文章中描述的技术合并整个文件的排序,然后按顺序运行它以删除重复项。
如果文章不够清楚,请查看引用的实现,例如this one。
答案 1 :(得分:1)
你可以制作第二个文件,其中包含记录,每个记录是64位CRC加上字符串和文件的偏移量应该被索引以便快速搜索。 像这样:
ReadFromSourceAndSort()
{
offset=0;
while(!EOF)
{
string = ReadFromFile();
crc64 = crc64(string);
if(lookUpInCache(crc64))
{
skip;
} else {
WriteToCacheFile(crc64, offset);
WriteToOutput(string);
}
}
}
如何制作好的缓存文件?它应按CRC64排序以快速搜索。所以你应该像二进制搜索树那样制作这个文件的结构,但是快速添加新项目而不移动文件中存在的文件。要提高速度,您需要使用Memory Mapped Files。
可能的答案:
memory = ReserveMemory(100 Mb);
mapfile= MapMemoryToFile(memory, "\\temp\\map.tmp"); (File can be bigger, Mapping is just window)
currentWindowNumber = 0;
while(!EndOfFile)
{
ReadFromSourceAndSort(); But only for first 100 Mb in memory
currentWindowNumber++;
MoveMapping(currentWindowNumber)
}
和功能查找; Shuld不使用映射(因为每个窗口切换节省100 Mb到HDD并加载100 Mb的下一个窗口)。只需寻找CRC64的100Mb树,如果CRC64找到 - >字符串已存储