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

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

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

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

2、字典的使用。使用字典减少了查找MD5值和查找文件大小是否相同的时间。并且通过该代码学习到了字典中{键,值}中的值可以为列表。

3、获取文件属性的方法。原先只知道可以通过os.path模块来获取文件属性(os.path.getsize()获取文件大小、os.path.ctime()为文件创建时间、os.path.atime()最后访问时间、os.path.mtime()最后修改时间)。现在知道了可以通过函数os.stat(path)来获取文件的属性。os.stat(path)返回包含文件属性的九元组。

《Python实现删除目录下相同文件》学习到的知识_第1张图片

《Python实现删除目录下相同文件》学习到的知识_第2张图片

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

自己编写的查找并删除相同文件的代码如下:

 

#! /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值。

 

#! /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")

 

你可能感兴趣的:(《Python实现删除目录下相同文件》学习到的知识)