拯救松鼠黨!教你零基礎(chǔ)用python實現(xiàn)去重文件&釋放空間

-- 系列:日常辦公技巧

-- 作者:alex tang

-- 時間:01/21-2019

一、業(yè)務(wù)背景

1.1背景簡介

幾年的咨詢工作不僅讓我變得更有經(jīng)驗,更養(yǎng)成了我松鼠黨的習慣。堆積的資料越來越多,而且重復(fù)的文件被放在了不同的目錄,占用的空間越來越大,數(shù)量也多得已經(jīng)不太適合人工分辨整理。尤其是有的一模一樣的文件被改成不一樣的名字,但實質(zhì)相同。這種壞現(xiàn)象不僅是電腦,連云盤也是如此。

前兩天整理自己的網(wǎng)盤時發(fā)現(xiàn)空間已滿,想要使用使用其文件去重功能居然要開通會員,最低一檔需付費30大洋。作為科技宅遂決定不讓自己的python吃灰了,自己寫著玩玩。

本文會和大家分享如何實現(xiàn)文件去重,如何掃描自己硬盤和網(wǎng)盤的每一個目錄。

1.2知識點預(yù)告

本文完成過程中將使用:

  • MD5原理
  • 遍歷文件夾
  • pathlib模塊的使用
  • logging模塊的使用

1.3使用環(huán)境

python=3.6.7
pathlib=2.3.2

二、實現(xiàn)原理

在開始之前,我先解釋一下這些代碼運行的原理——基于文件的完整性( integrity)。如果兩個文件的內(nèi)容相同,不管它們文件名相同與否,它們的MD5值(或者其他哈希算法值)必定是相同的。在這篇文章里,我使用MD5值來判斷文件的完整性。

三、開發(fā)準備

linux打開終端,windows使用win+r打開cmd命令行。進入code目錄,創(chuàng)建work文件夾,將其作為工作目錄。

! cd C:\test\Code&&mkdir work&&cd work
子目錄或文件 work 已經(jīng)存在。

為了實驗,我在該文件夾下面放了一個文件,并復(fù)制了一下。這樣兩個文件的名字就不相同了。


mission001_01.PNG

安裝所需模塊

! pip install hashlib
! pip install logging
! pip install pathlib

四、開發(fā)步驟

4.1導(dǎo)入所需package

import os
import hashlib
import logging
import sys
from pathlib import Path

4.2編寫日志函數(shù)

指定logger輸出格式,明確日志文件名稱和存儲位置,制定日志的最低輸出級別。

def logger():
    """ 獲取logger"""
    logger = logging.getLogger()
    if not logger.handlers:
        # 指定logger輸出格式
        formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')
        # 文件日志
        file_handler = logging.FileHandler("test.log")
        file_handler.setFormatter(formatter)  # 可以通過setFormatter指定輸出格式
        # 控制臺日志
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.formatter = formatter  # 也可以直接給formatter賦值
        # 為logger添加的日志處理器
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)
        # 指定日志的最低輸出級別,默認為WARN級別
        logger.setLevel(logging.INFO)
    return logger

4.3獲得文件的唯一標識 - MD5值

假如你要處理的重復(fù)文件有不同的文件名,最簡單的辦法就是通過MD5來確定兩個文件是不是一樣的。

def md5sum(filename, blocksize=65536):
    hash = hashlib.md5()
    with open(filename, "rb") as f:
        for block in iter(lambda: f.read(blocksize), b""):
            hash.update(block)
    return hash.hexdigest()

這個方法可以快速獲得一個文件的MD5值,blocksize 可以根據(jù)文件大小和CPU性能調(diào)整,一般選擇的值約等于文件的平均大小。

4.4保存所有文件標識和路徑

接下來遍歷所有文件,使用MD5作為key,路徑作為value,保存起來。

dup = {}

def build_hash_dict(dir_path, pattern='*.xlsx'):
    
    def save(file):
        hash = md5sum(file)
        if hash not in dup.keys():
            dup[hash] = [file]
        else:
            dup[hash].append(file)

    p = Path(dir_path)
    for item in p.glob('**/' + pattern):
        save(str(item))

4.5處理重復(fù)文件

最后一步非常簡單,把上一步建立的字典做一個簡單的過濾就能找到重復(fù)文件。

def main():
    log = logger()
    def get_duplicate():
        return {k: v for k, v in dup.items() if len(v) > 1}

    build_hash_dict(work_path)
    for hash, files in get_duplicate().items():
        log.info("{}: {}".format(hash, files))

如果你想直接刪除冗余文件,而不是自己來判斷從哪個文件里面刪除,可在記錄日志后遍歷日志文件列表,刪除指定文件之外的其他文件內(nèi)容。

    #import os
    #[os.remove(file) for file in files[1:]]

4.6某度網(wǎng)盤查重

原理是一樣的,某度網(wǎng)盤在Windows上安裝后會生成本地數(shù)據(jù)庫,經(jīng)測試是sqlite的,簡直和python不要太友好。我們直接訪問Windows下的百度網(wǎng)盤數(shù)據(jù)庫,通過判斷文件的MD5碼就可以進行去重。就不上代碼了,如果大家需要可以留言聯(lián)系我索取。

執(zhí)行過程中不需要登錄你的百度網(wǎng)盤賬號,你也就不用怕賬號被盜了吧。

4.7執(zhí)行函數(shù)代碼

if __name__ == '__main__':
    dup = {}
    work_path = 'C:\\test\\Code\\work'
    main()
2019-01-20 19:37:43,267 INFO    : bea3107f0ef871594bedcd992265ade4: ['C:\\test\\Code\\work\\abtForCustomValue-2 - 副本 - 副本.xlsx', 'C:\\test\\Code\\work\\abtForCustomValue-2 - 副本.xlsx']

五、代碼獲取

如果您想獲得完整代碼或者封裝好的exe程序,可以給我留言。如果你有建議或者想法,也歡迎留言與我溝通。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容