2016-10-14 67 views
0

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

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

+3

您是否尝试过计算文件的校验和而不是读取它们? – Prashant

+0

我直接使用FileUtils.contentEquals方法来检查文件以查找并存储结果。 – Mostafizur

+0

@Prashant你能给我写一个示例代码吗? – Mostafizur

回答

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

使用HashTable并将文件内容的MD5散列存储为键和文件路径作为值。无论内容大小如何,MD5散列大小都是16个字节。因此,如果您的文件每个都是150 GB或更大,则无关紧要。当你遇到一个新文件时,计算它的MD5散列值并检查它是否已经在HashTable中。查找和插入散列表将被摊销O(1)。另外,MD5碰撞的机会很少。所以为了避免误报,你可以检查文件内容。

注意:我没有注意到@samgak已经给出了一个详尽的答案。您可以使用他的答案代码片段:)