我们有一个150 Gb的数据文件夹。其中,文件内容是任何格式(doc,jpg,png,txt等)。我们需要相互检查所有文件内容,以检查是否存在重复的文件内容。如果是,则打印文件路径名称列表。为此,首先我使用ArrayList<File>
来存储所有文件,然后使用FileUtils.contentEquals(file1, file2)
方法。当我尝试使用少量文件(文件夹)时它可以正常工作但是对于这个150Gb的数据文件夹,它没有显示任何结果。我认为首先将所有文件存储在ArrayList中会产生问题。 JVM堆问题,我不确定。
任何人都有更好的建议和示例代码来处理这些数据?请帮我。
答案 0 :(得分:4)
计算每个文件的MD5 hash并存储在HashMap中,其中MD5哈希为键,文件路径为值。将新文件添加到HashMap时,可以轻松检查是否已存在具有该MD5哈希的文件。
错误匹配的可能性非常小,但如果您愿意,可以使用FileUtils.contentEquals来确认匹配。
e.g:
void findMatchingFiles(List<String> filepaths)
{
HashMap<String, String> hashmap = new HashMap<String, String>();
for(String filepath in filepaths)
{
String md5 = getFileMD5(filepath); // see linked answer
if(hashmap.containsKey(md5))
{
String original = hashmap.get(md5);
String duplicate = filepath;
// found a match between original and duplicate
}
else
{
hashmap.put(md5, filepath);
}
}
}
如果有多个相同的文件,则会找到每个文件与第一个相匹配的文件,但不是所有文件彼此匹配。如果你想要后者,你可以将MD5字符串中的哈希存储到文件路径列表中,而不是仅存储到第一个。
答案 1 :(得分:1)
使用HashTable并将文件内容的MD5哈希值存储为键,将文件路径存储为值。无论内容大小如何,MD5散列大小都是16字节。因此,如果您的文件各为150 GB或更大,则无关紧要。当您遇到新文件时,计算其MD5哈希并检查它是否已在HashTable中。哈希表中的查找和插入将分摊O(1)
。此外,MD5几乎没有碰撞的机会。因此,为避免误报,您可以检查匹配的文件内容。
注意:在写@samgak时,我没有注意到已经给出了详细的答案。你可以使用他的答案代码片段:)