《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")
相關文章
相關標籤/搜索