使用Python查詢重複檔案


複製檔案在我們電腦上積累資訊時會佔用額外的硬碟空間,這是一個常見的現象,因此,手動查詢和刪除重複檔案既費時又費力;幸運的是,我們可以使用Python自動化這個過程,在本教程中,我們將學習如何使用一個簡短的指令碼實現這一點。

設定

在本教程中,我們將使用Python中內建的`os`和`hashlib`模組,因此無需安裝任何額外的軟體包。

import os
import hashlib

演算法

  • 建立一個名為`hashfile()`的函式,該函式使用SHA-1演算法為檔案生成唯一的雜湊值,它接受檔名作為輸入並返回雜湊值。

  • 定義`find_duplicates()`方法,允許搜尋特定目錄中的重複檔案;它生成一系列列表,每個引數(例如目錄名)都包含重複檔案的路徑。

  • 在`find_duplicates()`方法內部,將每個目錄檔案的雜湊值儲存在一個字典中,並使用`hashfile()`方法迭代計算每個目錄檔案的雜湊值。

  • 如果雜湊值已存在於字典中,則將檔案路徑新增到重複檔案的列表中。否則,字典將新增雜湊值和檔案路徑。

  • 由於這些內部列表實際上不包含重複檔案路徑,因此將它們過濾掉。

示例

import os
import hashlib
def hashfile(filename):
   with open(filename, 'rb') as f:
      hasher = hashlib.sha1()
      while True:
         data = f.read(1024)
         if not data:
            break
         hasher.update(data)
      return hasher.hexdigest()

這段程式碼使用Python的`hashlib`模組建立`hashfile()`方法,上述方法返回檔案的SHA-1雜湊值,並接受檔名作為輸入。當一次讀取檔案的1024個位元組時,該函式會修改每個塊的雜湊值。該函式在讀取完整個檔案後,返回雜湊值的`hexdigest`作為字串。

def find_duplicates(dirname):
   files = os.listdir(dirname)
   if len(files) < 2:
      return
   hashes = {}
   for filename in files:
      path = os.path.join(dirname, filename)
      if not os.path.isfile(path):
         continue
      file_hash = hashfile(path)
      if file_hash not in hashes:
         hashes[file_hash] = path
      else:
         print(f'Duplicate found: {path} and {hashes[file_hash]}')

這段程式碼中的`find_duplicates()`方法定義了一個列表列表,其中包含重複檔案的路徑,並接受目錄名作為輸入。該函式建立一個空的重複列表和一個空的字典檔案,分別用於儲存重複檔案的路徑和目錄中每個檔案的雜湊值。使用`os.listdir()`方法,程式碼迭代目錄中的每個檔案,並使用`os.path.isfile()`函式確定它是否是一個檔案。

該函式使用前面定義的`hashfile()`函式為每個檔案建立一個雜湊值,並檢查雜湊值是否已存在於檔案的字典中。如果雜湊值已存在,則該函式將當前檔案路徑和具有相同雜湊值的先前檔案的路徑新增到重複列表中。該函式最終返回所有找到的重複檔案的列表。

最後呼叫該方法以執行整個指令碼 -

if __name__ == '__main__':
   show_duplicates('.')

解釋

因此,整個程式碼可以寫成 -

import os
import hashlib
def hashfile(filename):
   with open(filename, 'rb') as f:
      hasher = hashlib.sha1()
      while True:
         data = f.read(1024)
         if not data:
            break
         hasher.update(data)
      return hasher.hexdigest()
 
def find_duplicates(dirname):
   files = os.listdir(dirname)
   if len(files) < 2:
      return
   hashes = {}
   for filename in files:
      path = os.path.join(dirname, filename)
      if not os.path.isfile(path):
         continue
      file_hash = hashfile(path)
      if file_hash not in hashes:
         hashes[file_hash] = path
      else:
         print(f'Duplicate found: {path} and {hashes[file_hash]}')
            
if __name__ == '__main__':
   show_duplicates('.')

輸出

[您可以將多個檔案複製貼上到執行指令碼的目錄中以獲得所需的輸出]

Duplicate found: .\DSA-guide-2023.pdf and .\DSA-guide-2023 - Copy.pdf
  • 我們首先匯入`os`模組,該模組提供與作業系統互動的方法。

  • 然後定義`find_duplicates`函式,該函式接受一個目錄作為輸入,並返回在給定目錄中找到的所有重複檔案的列表。

  • `hash_dict`變數是將用於儲存每個檔案雜湊值的字典。

  • `duplicates`變數是一個列表,將儲存發現為重複檔案的任何檔案的路徑。

  • 然後,我們使用`os.walk`函式遍歷目錄及其子目錄。

  • 對於目錄中的每個檔案,我們使用`hash_file`函式來計算其雜湊值。

  • 然後,我們檢查`hash_dict`字典中是否存在該雜湊值。如果存在,則將當前檔案的路徑和之前具有相同雜湊值的檔案的路徑新增到`duplicates`列表中。如果不存在,則將雜湊值和檔案路徑新增到`hash_dict`字典中。

  • 返回`duplicates`列表,其中包含所有找到的重複檔案,並將其打印出來。

結論

即使可能涉及一些開銷,識別重複檔案對於保持我們系統井井有條至關重要。在這篇文章中,我們展示瞭如何使用Python的`os`模組和`hashlib`模組來查詢目錄中重複的檔案。`os`模組簡化了作業系統通訊,而`hashlib`模組允許我們訪問檔案的雜湊值。透過結合這兩個模組,我們能夠構建“查詢重複項”函式,該函式能夠在目錄中查詢重複檔案。

更新於:2023年8月21日

2K+ 次瀏覽

開啟您的職業生涯

透過完成課程獲得認證

開始
廣告
© . All rights reserved.