從上篇轉帖的《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")