用Python检测重复文件

用Python检测重复文件,python,Python,我正在尝试用Python编写一个脚本,用于对文件(照片、视频)进行排序、检查每个文件的元数据、查找所有副本并将其移动到单独的目录中。被元数据检查部分卡住了。trusted os.stat-对于重复文件不返回True。理想情况下,我应该能够做到以下几点: if os.stat("original.jpg")== os.stat("duplicate.jpg"): shutil.copy("duplicate.jpg","C:\\Duplicate Folder") 给谁指点方向?你

我正在尝试用Python编写一个脚本,用于对文件(照片、视频)进行排序、检查每个文件的元数据、查找所有副本并将其移动到单独的目录中。被元数据检查部分卡住了。trusted os.stat-对于重复文件不返回True。理想情况下,我应该能够做到以下几点:

if os.stat("original.jpg")== os.stat("duplicate.jpg"):  
    shutil.copy("duplicate.jpg","C:\\Duplicate Folder") 

给谁指点方向?

你可以做几件事。您可以比较每个文件的内容或散列,也可以检查os.stat结果中的一些select属性,例如

def is_duplicate(file1, file2):
    stat1, stat2 = os.stat(file1), os.stat(file2)
    return stat1.st_size==stat2.st_size and stat1.st_mtime==stat2.st_mtime

如果两个文件具有相同的
md5
,则它们是完全重复的

from hashlib import md5
with open(file1, "r") as original:
    original_md5 = md5(original.read()).hexdigest()
    with open(file2, "r") as duplicate:
       duplicate_md5 = md5(duplicate.read()).hexdigest()
       if original_md5 == duplicate_md5:
          do_stuff()

在您的示例中,您使用的是
jpg
文件,在这种情况下,您希望调用方法
open
,其第二个参数等于
rb
。有关详细信息,请参阅使用
集合跟踪已遇到文件的基本循环的文档:

import glob
import hashlib

uniq = set()
for fname in glob.glob('*.txt'):
    with open(fname,"rb") as f:
        sig = hashlib.sha256(f.read()).digest()
        if sig not in uniq:
            uniq.add(sig)
            print fname
        else:
            print fname, " (duplicate)"
请注意,与任何哈希函数一样,有一点可能会发生错误。这是两个具有相同摘要的不同文件。根据您的需要,这是可以接受的,当然不是

根据:

“例如,对于SHA-256(n=256)和10亿条消息(p=109),则[碰撞]的概率约为4.3*10-60。”


根据您的需要,如果您必须检查其他属性以识别“真实”重复项,请将
sig=..
行更改为适合您的内容。例如,如果需要检查返回的“相同内容”和“相同所有者”(
st_uid
),请编写:

提供有关某些文件元数据和功能的信息,包括创建时间。如果要确定两个文件是否相同,这不是一个好方法

例如:两个文件可以相同,但创建时间不同。因此,在这里比较统计数据将失败。结合性能和准确性时,Sylvain Leroux方法是最好的方法,因为两个不同的文件具有相同的哈希非常罕见

所以,除非你有一个难以置信的大数据量和一个重复的文件会导致系统死亡,否则这就是方法


如果这是你的情况(似乎不是),那么。。。您可以100%确保两个文件相同的唯一方法是迭代,并对每个字节执行比较。

使用“检查每个文件的元数据”是否足够?相同的内容?或者相同的内容和相同的元数据(哪些?)副本是具有相同内容的文件,因此我假设它们也具有相同的元数据(在所有字段中)。我可能错了。我的操作系统是Windows 7 Home Basic请查看标准库中的
filecmp
模块。如果两个文件具有相同的
md5
它们是完全重复的
    sig = ( hashlib.sha256(f.read()).digest(), 
            os.stat(fname).st_uid )