使用Python实现文件查重功能

 更新时间:2024年12月30日 11:29:52   作者:hvinsion  
这篇文章主要为大家详细介绍了Python如何通过循环进行删除重复文件,从而达到文件查重功能,文中的示例代码讲解详细,需要的小伙伴可以参考下

1.简介

这是一个Python文件去重的工具,市面上很多检测重复工具的软件,都是要付费或者要破解的。于是就想着能不能自己做一个后台每时每刻都可以自己去重的工具。虽然市面上很多检测重复工具的软件. 但是这个工具使用环境和那些工具很不一样。 别的工具删重复文件, 都是扫描,自己删除.。需要人工值守.。这边的工具扫描删除不需要人工值守,并且可以后台运行。这边设置好了,就可以吃着火锅唱着歌干别的去了。只要电脑不断电可以一直运行操作。别的软件必须得等扫描完,才能做下一步操作,这个是本质区别。

2.工具功能

1 通过检测MD5,来判断是否有文件重复,检测过后,可以自行选择删除或者不删除,.或者移动到回收站还是直接删除。

2 循环检测指定目录的重复文件,只要是新生成了重复文件,就会立刻被删除。

3 删除默认会保留最早的文件。

**注:**只要文件属性不一样,即使文件名一样也能查重成功。

3.运行效果

4.相关源码

import sys, os, filecmp
import time
from win32com.shell import shell,shellcon



def deltorecyclebin(filename):
    #print('deltorecyclebin', filename)
    # os.remove(filename) #直接删除文件,不经过回收站
    res= shell.SHFileOperation((0,shellcon.FO_DELETE,filename,None, shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,None,None))  #删除文件到回收站
    #print(res)
        # if not res[1]:
        #     os.system('del '+filename)

#清理重复文件
def md5(fname, chunk_size=1024):
    import hashlib
    hash = hashlib.md5()
    with open(fname, "rb") as f:
        chunk = f.read(chunk_size)
        while chunk:
            hash.update(chunk)
            chunk = f.read(chunk_size)
    return hash.hexdigest()

def check_for_duplicates(dufilelist):    
    sizes = {}
    hashes = {}
    duplicates = []
    # Traverse all the files and store their size in a reverse index map
    # 遍历所有文件并将其大小存储在反向索引映射中
    files_count = 0
    #print(dufilelist)
    for s in dufilelist:
        for root, _dirs, files in os.walk(s, topdown=True, onerror=None, followlinks=False):
            files_count += len(files)
            for f in files:
                file = os.path.join(root, f)
                size = os.stat(file).st_size
                if size not in sizes:
                    sizes[size] = []
                sizes[size].append(file)
    #print("Traversed {} files".format(files_count))

    # Remove empty files from the size map
    # 从大小映射中删除空文件
    if 0 in sizes:
        del sizes[0]

    # Remove files with unique sizes from the size map
    # 从大小映射中删除具有唯一大小的文件
    for (key, value) in list(sizes.items()):
        if len(value) == 1:
            del sizes[key]

    # Traverse the size map and enrich it with hashes
    # 遍历大小映射并用哈希值丰富它
    for (size, files) in sizes.items():
        for file in files:            
            try:
                hash = md5(file)
            except:
                continue 
            tuple = (size, hash)
            if tuple not in hashes:
                hashes[tuple] = []
            hashes[tuple].append(file)

    # Remove files with unique (size, hash) tuple in hash map
    # 删除哈希映射中具有唯一(大小,哈希)元组的文件
    for (key, value) in list(hashes.items()):
        if len(value) == 1:
            del hashes[key]

    # Compare file pairs
    # 比较文件对    
    for possible_list in hashes.values():
        #print(possible_list)
        #这里把文件按着时间排序:
        if possible_list:
            # 注意,这里使用lambda表达式,将文件按照最后修改时间顺序升序排列
            # os.path.getmtime() 函数是获取文件最后修改时间
            # os.path.getctime() 函数是获取文件最后创建时间
            possible_list = sorted(possible_list,key=lambda x: os.path.getctime(x))
        

        while possible_list:
            first = possible_list[0]
            copy = [first]
            for other in possible_list[1:]:
                if filecmp.cmp(first, other, shallow=False):
                    copy.append(other)
            for c in copy:
                possible_list.remove(c)
            duplicates.append(copy)

    #print(duplicates)
    # Print duplicates
    # 打印相同  
    groupready=[]
    for _i, group in enumerate(duplicates):
        print("第 " + str(int(_i) + 1) + " 组")
        assert len(group) > 1
        #print("%r:" % (i + 1))
        if onlyprint: 
            for d in group:
                pass
                print("发现相同文件:  %r" % (d))
            for d in group[1:]:
                groupready.append(d)

            #print("全部要删除的文件: "+str(groupready))

        else:
            if filedelete:
                for d in group[1:]:
                    os.remove(d)
                    print("直接删除重复文件%r" % (d))
            else:
                for d in group[1:]:
                    deltorecyclebin(d)
                    print("回收重复文件%r" % (d))
                


    if not duplicates:
        print("目录里没有找到重复文件")


    if len(groupready)>0:
        print("--------------------------------分割线------------------------------------------")
        print("下面列出重复的文件:")
        for num in groupready:
            print(num)

        reback=input("输入d直接删除以上的重复文件, ,输入r将以上重复文件放入回收站,,取消请任意输入n或者关闭本窗口.请输入: d/r/n:")
        if reback=="d":
            for num in groupready:
                os.remove(num)
                print("直接删除重复文件%r" % (num)) 
        elif reback=="r":
            for num in groupready:
                deltorecyclebin(num)
                print("回收重复文件%r" % (num)) 
        else: 
            print("取消操作")







if __name__ == "__main__":        
    loopinfo=input("是否循环检测重复文件? y/n:")
    if loopinfo=="y":
        loopinfoable=-1
    else:
        loopinfoable=1

    onlyprintAble=input("只检测重复文件请输入y,检测并且自动删除重复文件请输入n y/n:")
    if onlyprintAble=="y":
        onlyprint=True   
    else:
        onlyprint=False   
        filedeleteAble=input("重复文件放入回收站请输入y ,直接删除重复文件请输入n y/n:")
        if filedeleteAble=="y":
            filedelete=False   #是否强制删除
        else:
            filedelete=True   #是否强制删除



    filepath=input("请输入要检测重复文件的目录:")    

    time_start=time.time()

    while loopinfoable: 
        loopinfoable=loopinfoable-1   
        
        
        print("程序开始...请等待一会...我正在努力为主人干活中o(´^`)o...")
        dufilelist=[filepath]    
        check_for_duplicates(dufilelist)


        
        #下面是计算时间
        time_end=time.time()
        seconds=time_end-time_start
        m, s = divmod(seconds, 60)
        h, m = divmod(m, 60)
        print('当前程序总共用时:%02d:%02d:%02d' % (h, m, s))        
        if loopinfoable!=0: #不循环
            time.sleep(3)

    input("程序结束,按回车退出")

到此这篇关于使用Python实现文件查重功能的文章就介绍到这了,更多相关Python文件查重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解 Python 中的多线程 新手必看

    深入理解 Python 中的多线程 新手必看

    你应当将下边的例子运行多次,以便可以注意到线程是不可预测的和线程每次运行出的不同结果。声明:从这里开始忘掉你听到过的关于GIL的东西,因为GIL不会影响到我想要展示的东西
    2016-11-11
  • python矩阵运算,转置,逆运算,共轭矩阵实例

    python矩阵运算,转置,逆运算,共轭矩阵实例

    这篇文章主要介绍了python矩阵运算,转置,逆运算,共轭矩阵实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • Python实现的拉格朗日插值法示例

    Python实现的拉格朗日插值法示例

    这篇文章主要介绍了Python实现的拉格朗日插值法,简单介绍了拉格朗日插值法的原理并结合完整实例形式给出了拉格朗日插值法的具体实现与使用技巧,需要的朋友可以参考下
    2019-01-01
  • Python无头爬虫下载文件的实现

    Python无头爬虫下载文件的实现

    这篇文章主要介绍了Python无头爬虫下载文件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 稳扎稳打学Python之容器 可迭代对象 迭代器 生成器专题讲解

    稳扎稳打学Python之容器 可迭代对象 迭代器 生成器专题讲解

    在刚开始学Python的时候,是不是经常会听到大佬们在讲容器、可迭代对象、迭代器、生成器、列表/集合/字典推导式等等众多概念,其实这不是大佬们没事就搁那扯专业术语来装B,而是这些东西都得要明白的,光知道字符串、列表等基础还是不够的,尤其是在Python的数据结构方面
    2021-10-10
  • 六个Python3中使用最广泛的内置函数总结

    六个Python3中使用最广泛的内置函数总结

    这篇文章主要为大家详细介绍了六个Python3中使用最广泛的内置函数:Lamdba 函数、Map 函数、Filter 函数、Reduce 函数、Enumerate 函数和Zip 函数,需要的可以参考一下
    2022-08-08
  • pandas如何解决excel科学计数法问题

    pandas如何解决excel科学计数法问题

    这篇文章主要介绍了pandas如何解决excel科学计数法问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Python编程之字符串模板(Template)用法实例分析

    Python编程之字符串模板(Template)用法实例分析

    这篇文章主要介绍了Python编程之字符串模板(Template)用法,结合具体实例形式分析了Python字符串模板的功能、定义与使用方法,需要的朋友可以参考下
    2017-07-07
  • Python实现 MK检验示例代码

    Python实现 MK检验示例代码

    这篇文章主要介绍了Python实现 MK检验,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • python字符串查找函数的用法详解

    python字符串查找函数的用法详解

    在本篇内容里小编给各位整理的是关于python字符串查找函数的使用的知识点内容,有需要的朋友们跟着学习参考下。
    2019-07-07

最新评论