前言
最近要開發一個基於python的合並文件夾/目錄的程序,本來的想法是基於修改時間的比較,即判斷文件有沒有改變,比較兩個文件的修改時間即可。這個想法在windows的pc端下測試沒有問題。
但是當把一個文件從pc端復制到優盤時出現了一個問題,復制到優盤的文件比pc端的文件慢了兩秒鍾!
這里我用的復制函數是 shutil.copy2(),理論上它會把修改時間和最后訪問時間也復制過來1,但是實際情況並不是完全相同。
詳細情況我在segmentfault里提出了問題:為什么將一個文件從pc中復制到優盤中修改時間會慢2秒鍾?
看shutil.copy2的資料和網上的解答,發現可能是文件系統的差別造成的,windows的pc端文件系統是ntfs,優盤的是fat32。但還是想了解更深層的原因,希望知道的大神解答一下。
扯遠了,基於以上問題的出現,迫使我得修改比較策略,於是我找到了用文件的MD5值比較的方法,yeah!~
具體來說,每個文件都會有一個MD5的加密值,這個值來唯一標識這個文件(百度雲的快速上傳/秒傳就是基於這個道理),它常用來辨別文件的真偽,例如下載系統安裝鏡像,旁邊會附帶一個長長的字符亂碼,這就是這個鏡像的MD5值。
文件被修改后其MD5值也會改變,所以可以用來判斷一個文件是否被修改過。
這樣的方法比基於時間的比較顯然更加可靠,現在唯一的問題就是MD5計算時間的問題。一個大文件計算MD5值要多久呢?
網上的解決代碼已經有很多了,大都是兩種方法,一種是小文件的MD5加密,調用函數直接加密即可,另一種是大文件的MD5加密策略,方法是將大文件分塊更新MD5值,最后得到最終的值。
下面我使用第二種方法對大文件進行加密測試。
測試1
測試對象是一個將近2G的壓縮文件,如下:
加密結果如下:
運行時間是20s,不快也不慢,相對文件大小來說,我還是能接受這個速度……
計算出的MD5值是“8ee04176f69c10ca56f2358d51d792ed”,這個值對不對呢?我在網上做了驗證:
兩個值相等,由此可見該算法,計算正確。測試代碼見下。
測試網址在這:http://www.atool.org/file_hash.php
有趣的是,我對文件進行了第二次、第三次、第四次加密,發現加密時間少了5秒左右,好神奇,不知道為什么。
搞定了MD5加密,我可以繼續進行下一步開發了~ :)
大文件的MD5加密代碼
1 # coding=gbk 2 3 import hashlib 4 import os 5 import datetime 6 7 def GetFileMd5(filename): 8 if not os.path.isfile(filename): 9 return 10 myhash = hashlib.md5() 11 f = open(filename,'rb') 12 while True: 13 b = f.read(8096) 14 if not b : 15 break 16 myhash.update(b) 17 f.close() 18 return myhash.hexdigest() 19 20 filepath = raw_input('請輸入文件路徑:') 21 22 # 輸出文件的md5值以及記錄運行時間 23 starttime = datetime.datetime.now() 24 print GetFileMd5(filepath) 25 endtime = datetime.datetime.now() 26 print '運行時間:%ds'%((endtime-starttime).seconds)
參考資料
原創聲明
Freecode# : www.cnblogs.com/yym2013