使用Java检查重复文件内容

时间:2016-10-14 08:40:03

标签: java algorithm collections checksum fileutils

我们有一个150 Gb的数据文件夹。其中,文件内容是任何格式(doc,jpg,png,txt等)。我们需要相互检查所有文件内容,以检查是否存在重复的文件内容。如果是,则打印文件路径名称列表。为此,首先我使用ArrayList<File>来存储所有文件,然后使用FileUtils.contentEquals(file1, file2)方法。当我尝试使用少量文件(文件夹)时它可以正常工作但是对于这个150Gb的数据文件夹,它没有显示任何结果。我认为首先将所有文件存储在ArrayList中会产生问题。 JVM堆问题,我不确定。

任何人都有更好的建议和示例代码来处理这些数据?请帮我。

2 个答案:

答案 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时,我没有注意到已经给出了详细的答案。你可以使用他的答案代码片段:)