我建議你從每個文件的內容計算一個「散列」。創建一個字典,其中的鍵是哈希值,並且這些值是文件名列表。
Python hashlib
模塊有多個可以使用的散列算法。我建議SHA-1或MD-5。
這兩個不相同的文件非常不可能具有相同的散列值。如果你想絕對確定,你可以遍歷一個文件列表並比較實際的文件值,以確保它們確實相同。
您可以使用defaultdict
使這個更簡單:How does collections.defaultdict work?
這僅僅是未經測試的僞代碼,但這樣做:
from collections import defaultdict
import hashlib
h = defaultdict(list)
for filename in list_of_files_in_directory:
with open(filename, "r") as f:
data = f.read()
fhash = hashlib.sha1(data).hexdigest()
h[fhash].append(filename)
# h now contains a key for each unique file contents hash, and a list of filenames for each key
你的字典可以只使用二進制散列數據作爲密鑰,但使用字符串值更方便。方法函數.hexdigest()
爲您提供了一個表示散列爲十六進制數字的字符串。
編輯:在評論中,@parchment建議使用os.stat()
來獲取文件大小,並且只有在有多個文件具有相同大小時才計算文件哈希值。這是加速找到相同文件的一個很好的方法;如果您只有一個文件具有特定的長度,則您知道它不能與任何其他文件相同。如果文件很大,計算哈希值可能會很慢。
但我會建議先編寫簡單的哈希代碼,並讓它工作,然後如果您有時間嘗試重寫它來檢查文件大小。檢查文件大小,然後有時還會散列文件的代碼會更復雜,因此更難以正確使用。
了我的頭頂部,這裏是我會怎樣改寫使用文件大小:
請叫done
空列表。這是存儲輸出的地方(內容相同的文件名列表)。
將字典映射文件長度爲文件名列表。如上所示,您可以使用defaultdict
。
循環遍歷字典。每個值都是一個包含單個文件名的列表,只需將該值附加到done
列表;唯一的長度意味着一個獨特的文件。每個值都是兩個或多個文件的列表,您現在需要計算散列值,並使用該散列值構建另一個字典映射散列值到文件列表。完成後,只需遍歷此字典中的所有值並將它們添加到done
。基本上這部分與散列所有文件的解決方案是相同的代碼;只是現在你不需要散列每個文件,只是具有非唯一長度的文件。
您可以先將文件大小與stat調用進行比較,然後使用相同大小對文件進行散列處理,以提高性能。散列1000個文件可能需要一段時間。 – parchment 2014-09-22 22:53:31