《Python实现删除目录下相同文件》学习到的知识

从上篇转帖的《Python实现删除目录下相同文件》中学到了不小东西,如今分享一下:python

一、md5值的求解。获取文件的MD5值的方法以下,即读取时以二进制方式读取文件内容,而后计算md5值。注意如下代码暂不支持中文路径,稍后进行改正。程序员

import os
import md5
def Getfilemd5(path):
    '''获取文件的消息摘要值'''
    fp=open(path,'rb')
    inf=fp.read()
    md=md5.new(inf)
    return md.hexdigest()

二、字典的使用。使用字典减小了查找MD5值和查找文件大小是否相同的时间。而且经过该代码学习到了字典中{键,值}中的值能够为列表。app

三、获取文件属性的方法。原先只知道能够经过os.path模块来获取文件属性(os.path.getsize()获取文件大小、os.path.ctime()为文件建立时间、os.path.atime()最后访问时间、os.path.mtime()最后修改时间)。如今知道了能够经过函数os.stat(path)来获取文件的属性。os.stat(path)返回包含文件属性的九元组。函数

四、time模块的使用。知道了能够经过time模块中的now()函数来获取程序执行前与执行后的时间差,来计算程序执行的时间。其实timeit模块能够帮助程序员对代码的执行时间进行计时。学习

本身编写的查找并删除相同文件的代码以下:code

 

#! /usr/bin/env python
#coding=utf-8
import os
import md5
def Getfilemd5(path):
    '''获取文件的消息摘要值'''
    fp=open(path,'rb')
    inf=fp.read()
    md=md5.new(inf)
    return md.hexdigest()

def main(top_dir):
    size_md5={}   #键是文件大小,值是拥有该文件大小的文件的md5值列表(为了减小计算md5的次数,当出现新的不一样大小的文件时
                  #并非立马去计算新文件的md5值,而是将文件路径保存在值中。等到再次出现该大小的文件时再计算第一个文件
                  #的MD5值再来比较)
    #思路:先获取文件大小,看是否存在相同大小存在,如不存在,将大小添加到file_size字典中,值是文件路径
    #若存在,则再判断本文件是不是第二个相同大小的文件,如是,则计算原来保存路径文件的md5进行比较,若已经不是第二个,
    #则直接计算本文件md5判断是否在列表中
    if os.path.isdir(top_dir)==False:
        print "wrong dir_path"
        return
    for dirname,dirs,filenames in os.walk(top_dir):
        for file in filenames:
            file_path=os.path.join(dirname,file)
            filepath_and_md5=[file_path]
            #获取大小
            file_size=os.path.getsize(file_path)
            if file_size in size_md5.keys():
                if len(size_md5[file_size])==1:
                    #计算保存的文件的md5值,保存在列表的[1]处
                    size_md5[file_size].append(Getfilemd5(size_md5[file_size][0]))
                #计算本文件的md5值
                now_md5=Getfilemd5(file_path)
                if now_md5 in size_md5[file_size]:   #不用怕,MD5值不会和保存的文件路径匹配,由于路径中有\等字符。
                    #发现相同文件,删除
                    print "delete"+file_path
                    os.remove(file_path)
                else:
                    size_md5[file_size].append(now_md5)
            else:
                size_md5[file_size]=filepath_and_md5

#调用函数
main(r"E:\tedian")

 

上面代码仍够发现相同的文件,可是不知谁和谁相同,下面改进代码中建一个字典(键为md5,值为md5对应的文件列表),而且建了一个列表用于保存相同文件的md5值。md5

 

#! /usr/bin/env python
#coding=utf-8
import os
import md5
#升级以后能够在最后打印哪一个文件到底和哪一个文件相同,但缺点是只有彻底遍历完后才会显示最后结果
def Getfilemd5(path):
    '''获取文件的消息摘要值'''
    fp=open(path,'rb')
    inf=fp.read()
    md=md5.new(inf)
    return md.hexdigest()

def main(top_dir):
    list_md5=[]  #保存重复文件的MD5值
    size_md5={}   
    all_md5={}  #保存全部的MD5与路径的对应关系,即字典的键是md5,值是文件列表
    if os.path.isdir(top_dir)==False:
        print "wrong dir_path"
        return
    for dirname,dirs,filenames in os.walk(top_dir):
        for file in filenames:
            file_path=os.path.join(dirname,file)
            filepath_and_md5=[file_path]
            #获取大小
            file_size=os.path.getsize(file_path)
            if file_size in size_md5.keys():
                if len(size_md5[file_size])==1:
                    #计算保存的文件的md5值,保存在列表的[1]处
                    file_md5=Getfilemd5(size_md5[file_size][0])
                    size_md5[file_size].append(file_md5)
                    all_md5[file_md5]=[size_md5[file_size][0]]
                #计算本文件的md5值
                now_md5=Getfilemd5(file_path)
                if now_md5 in size_md5[file_size]:   #不用怕,MD5值不会和保存的文件路径匹配,由于路径中有\等字符。
                    if (now_md5 in list_md5)==False:
                        list_md5.append(now_md5)
                    all_md5[now_md5].append(file_path)
                    #print "delete"+file_path
                    #os.remove(file_path)
                else:
                    size_md5[file_size].append(now_md5)
                    all_md5[now_md5]=[file_path]
            else:
                size_md5[file_size]=filepath_and_md5
    #打印结果
    for md5_same in list_md5:
        for path in all_md5[md5_same]:
            print path,
        print ""

#调用函数
main(r"C:\Users\Administrator\Desktop\q")
相关文章
相关标签/搜索