从上篇转帖的《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")