python - 通过 hashlib 查找重复文件?

标签 python file duplicates hashlib

我知道之前有人问过这个问题,我也看到了一些答案,但这个问题更多的是关于我的代码和完成这个任务的最佳方式。

我想扫描一个目录并查看该目录中是否有任何重复项(通过检查 MD5 哈希值)。以下是我的代码:

import sys
import os
import hashlib

fileSliceLimitation = 5000000 #bytes

# if the file is big, slice trick to avoid to load the whole file into RAM
def getFileHashMD5(filename):
     retval = 0;
     filesize = os.path.getsize(filename)

     if filesize > fileSliceLimitation:
        with open(filename, 'rb') as fh:
          m = hashlib.md5()
          while True:
            data = fh.read(8192)
            if not data:
                break
            m.update(data)
          retval = m.hexdigest()

     else:
        retval = hashlib.md5(open(filename, 'rb').read()).hexdigest()

     return retval

searchdirpath = raw_input("Type directory you wish to search: ")
print ""
print ""    
text_file = open('outPut.txt', 'w')

for dirname, dirnames, filenames in os.walk(searchdirpath):
    # print path to all filenames.
    for filename in filenames:
        fullname = os.path.join(dirname, filename)
        h_md5 = getFileHashMD5 (fullname)
        print h_md5 + " " + fullname
        text_file.write("\n" + h_md5 + " " + fullname)   

# close txt file
text_file.close()


print "\n\n\nReading outPut:"
text_file = open('outPut.txt', 'r')

myListOfHashes = text_file.read()

if h_md5 in myListOfHashes:
    print 'Match: ' + " " + fullname

这给了我以下输出:

Please type in directory you wish to search using above syntax: /Users/bubble/Desktop/aF

033808bb457f622b05096c2f7699857v /Users/bubble/Desktop/aF/.DS_Store
409d8c1727960fddb7c8b915a76ebd35 /Users/bubble/Desktop/aF/script copy.py
409d8c1727960fddb7c8b915a76ebd25 /Users/bubble/Desktop/aF/script.py
e9289295caefef66eaf3a4dffc4fe11c /Users/bubble/Desktop/aF/simpsons.mov

Reading outPut:
Match:  /Users/bubble/Desktop/aF/simpsons.mov

我的想法是:

1) 扫描目录 2) 将 MD5 哈希值 + 文件名写入文本文件 3)以只读方式打开文本文件 4) 再次扫描目录并检查文本文件...

我发现这不是一个好的方法,而且它不起作用。 “匹配”只是打印出最后处理的文件。

如何让这个脚本真正找到重复项?有人能告诉我完成这项任务的更好/更简单的方法吗?

非常感谢您的帮助。抱歉,这是一篇很长的文章。

最佳答案

识别重复项的明显工具是哈希表。除非您正在处理非常大的文件,否则您可以这样做:

from collections import defaultdict

file_dict = defaultdict(list)
for filename in files:
    file_dict[get_file_hash(filename)].append(filename)

在此过程结束时,file_dict 将包含每个唯一哈希的列表;当两个文件具有相同的哈希值时,它们都会出现在该哈希值的列表中。然后过滤 dict 以查找长度超过 1 的值列表,并比较文件以确保它们相同——像这样:

for duplicates in file_dict.values():   # file_dict.itervalues() in Python 2
    if len(duplicates) > 1:
        # double-check reported duplicates and generate output

或者这个:

duplicates = [files for files in file_dict.values() if len(files) > 1]

get_file_hash 可以使用 MD5;或者它可以像 Ramchandra Apte 在上面的评论中建议的那样简单地获取文件的第一个和最后一个字节;或者它可以简单地使用上面评论中 tdelaney 建议的文件大小。不过,后两种策略中的每一种都更有可能产生误报。您可以将它们结合起来以降低误报率。

如果您正在处理非常 大量文件,您可以使用更复杂的数据结构,例如Bloom Filter。 .

关于python - 通过 hashlib 查找重复文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18724376/

相关文章:

python - 如何在 PYTTS (Python) 中设置属性 : age, 性别或语言

python - 从歌曲中提取人声

java - 设置重复项 java - 从文件导入 - java

javascript - 防止谷歌脚本复制 protected 范围

python - 在Python中使用列表理解创建字典时获取重复值

python - 如何解决 MoviePy 使用大量内存的问题?

python - 获取每行的三个最小值并返回对应的列名

file - Gnome 文件 Nautilus 上下文菜单 "Open with"应用程序列表

html - 如何在 objective-c 中创建 html 文件?

php - 检测文件是否是PHP中没有mime类型的音频文件