還你系統空間的 Python 小程序

Windows 系統用久了,磁碟中就會產生大量的「垃圾」文件。這些文件有的是程序使用過的臨時文件,有的是操作記錄和日誌信息等。因為往往不能被有效地清理乾淨,越積越多,導致用戶的可用空間越來越小。同時也會因為碎片文件過多,使得系統的運行速度受到一定影響。

像我這種強迫症用戶顯然受不了這種狀況,定期清理垃圾文件很有必要。

對於 Windows 系統,網上有一些現成的垃圾文件清理腳本。不過作為一個 Python 學習者,當然要自己動手來實現一個才合理嘛。

Python 的 os 模塊,提供了較為豐富的處理系統文件與路徑的函數。下面我們就靠它,來實現一個自己的磁碟清理小程序。

動手前的友情提示:

  • 本文附帶代碼運行環境為 WIN7 + Python 2.7。

  • 某些緩存文件可以提高程序的執行速度,比如緩存 cookie、使用記錄 recent、預讀取 prefetch 等。所以清理臨時文件並不代表系統運行就會變快,有時也可能變慢。

  • 由於牽涉到文件刪除操作,請在動手前務必反覆確認代碼,萬一導致什麼重要文件被刪,本人可概不負責啊。別問我為什麼要這麼說,寫了好幾天的代碼在調試時被誤刪了,我再去哭一會兒……(;′??Д??`)

言歸正傳,電腦中的垃圾文件及文件夾主要有下面幾類:

系統盤 %system% 下文件類型:

【臨時文件(*.tmp)】

【臨時文件(*._mp)】

【日誌文件(*.log)】

【臨時幫助文件(*.gid)】

【磁碟檢查文件(*.chk)】

【臨時備份文件(*.old)】

【Excel備份文件(*.xlk)】

【臨時備份文件(*.bak)】

--------------------------------

用戶目錄 %userprofile% 下文件夾

【COOKIE】 cookies*.*

【文件使用記錄】 recent*.*

【IE臨時文件】 Temporary Internet Files*.*

【臨時文件文件夾】 Temp*.*

--------------------------------

Windows 目錄 %windir% 下文件夾

【預讀取數據文件夾】 prefetch*.*

【臨時文件】 temp*.*

如果你了解自己使用的軟體產生的其它垃圾文件,也可以添加至待刪除的列表上。

與我們直接在 Windows 可視化窗口刪除文件或文件夾類似,使用 Python 清理磁碟大致亦可分為 獲取文件地址判斷垃圾文件刪除垃圾文件和文件夾 三步:

1. 獲取文件地址

在可視化窗口中,我們點擊每個文件夾的圖標,打開不同文件夾,可以看見窗口的地址欄也隨之切換到了對應的目錄下,在 Python os 模塊中,同樣是根據文件地址來查找文件,相應的函數如下:

獲取當前目錄路徑

>>> import os>>> os.getcwd()E:\Software\Python27

跳轉至指定的文件目錄

>>> os.chdir(d://temporary)>>> os.getcwd()d:\temporary

獲取系統盤符

>>> os.environ[systemdrive]C:

獲取用戶目錄

>>> os.environ[userprofile]C:\Users\Administrator

獲取 Windows 目錄

>>> os.environ[windir]C:\Windows

調用 os.environ 函數得到字典格式的系統環境映射表,通過關鍵字可以很方便地得到我們想要的地址。

使用 os.walk 函數,可生成並展開以指定目錄為根目錄的目錄樹。

參數 topdown 指定展開方式是否從頂層到底層

all_info = os.walk(d:\temporary\, topdown=False)

os.walk() 函數一般配合如下的 for 循環使用,遍歷目錄樹中每一層的根目錄 roots,子目錄 dirs 以及文件 files,並將值儲存在對應的變數中:

for roots, dirs, files in all_info: ...

例如,對於 D 盤下根目錄 AAA 目錄樹展開如下:

用 walk 函數遍歷並輸出後,結果如下:

將兩個給定的目錄進行組合

>>> os.path.join(d:\, temporary)d:\temporary

用 join 函數,配合 walk 函數得到的根目錄與文件名,就能組合出我們想要的文件地址了。

2. 判斷垃圾文件

我們現在已知垃圾文件的擴展名(以及垃圾文件夾名),通過 walk 函數與 join 函數也得到了完整的文件名,要判斷文件是不是垃圾文件,可以用正則表達式進行匹配判斷,正則表達式還不牢固的同學請移步 【Python 第55課】 正則表達式(1)

如果對正則表達式的語法深感頭疼,os 模塊也有提供其它解決方案:

>>> os.path.splitext(raaabbccc.ddd)(aaa\bbb\ccc, .ddd)

os.path.splitext 函數可以將文件的文件名與擴展名進行分離,並返回一個包含文件名與擴展名的二元元組。

得到了文件的擴展名,我們可以用 『in』 來 判斷該擴展名是否在需要刪除的擴展名列表中:

extension = os.path.splitext(raaabbccc.ddd)extension_to_del = [.aaa, .bbb, .ccc, .ddd]if extension[1] in extension_to_del: # to be deleted

這裡可能會踩到的一個坑是字元「」,它既是 Windows 路徑的分隔符,又是 Python 字元串中的轉義符。在處理路徑時,需要額外注意。

3. 刪除文件

使用 os 模塊刪除數據有三點需要注意:

其一,刪除文件與刪除文件夾調用的是不同的函數。

刪除文件

os.remove(d:temporary/test/test.txt)

刪除文件夾

os.rmdir(d:temporary/test/empty)

如果你在嘗試調用這個代碼刪除文件/文件夾時無效,確認下文件名是否帶有中文、空格和特殊符號。建議先在純英文的簡單路徑下調試成功再說。

無法刪除的還有一個常見原因是另一個要注意的地方:

其二,os.rmdir 只能刪除空文件夾,如果文件夾非空,則會報錯。

所以,如果要把匹配到的垃圾文件夾整個刪除,可能我們不得不選擇先把文件夾中的所有文件全部刪除,再從最內層文件夾開始往外逐層刪除。這實在是挺麻煩的,那有沒有其它解決方案呢?

有,但要依靠 os 以外的幫助。

import shutilshutil.rmtree(d:/temporary/test/aaa)

上面的解決辦法是引用另外一個模塊 shutil 的函數來刪除非空文件夾,其實,這個外部引用的函數還是用 os 模塊的函數來寫的,想挑戰的話,也可以自己寫一個試試。

當然,直接調用 cmd 命令也是極好的:

os.system(rd/s/q "d:temporary/test")

注意,整個命令是一個字元串,其中目錄地址要額外加引號。

在某些情況下,尤其是當前有較多其它程序在運行時,即使用 shutil.rmtree 函數仍然會報錯,甚至連刪除文件都會報錯,這就是第三個注意事項了:

其三,文件正在運行或者受到保護、當前賬戶沒有足夠許可權時,刪除會報錯。

這個情況下,對應的文件最後就不要強行刪了,不然輕則即使刪除了,也會再次自動生成、重則還可能導致正在運行的程序崩潰。

因此,我們在刪除文件或文件夾時,加上一個 try except 邏輯結構,跳過那些無法刪除的文件:

try: os.remove(rd: emporaryusing.xxx)except WindowsError: print nothing has being removed

按照上面三個步驟寫下來,磁碟清理腳本基本功能已經完善。不過除此之外,我們還可以添加一些數據監控代碼,多一些對用戶友好的人機交互,比如:

顯示文件夾(路徑)大小,單位 bite

>>> os.path.getsize(d://temporary/test)4096

顯示文件大小

>>> os.path.getsize(d://temporary/test/aaa.txt)135

其它功能諸如 定時清理、開關機清理、清理時間統計 等等,都可以嘗試實現。歡迎在留言區和論壇上討論。

在公眾號(Crossin的編程教室)回復 清理,可獲取本文演示代碼。

其他文章及回答:

學習編程的過程中可能會走哪些彎路,有哪些經驗可以參考?

你是如何自學 Python 的?

數據分析:當趙雷唱民謠時他唱些什麼?

我去扒了杜蕾斯的微博

一行代碼掃出「敬業福」

今天,你搶到票了嗎?

爆款遊戲《貪吃蛇大作戰》的 Python 實現

Crossin的編程教室

微信公眾號ID:crossincode

網站:crossincode.com

QQ群:453300655

微信加群:crossin11


推薦閱讀:

為什麼Windows下,通過Hyper V安裝虛擬的其它Windows會這麼快?
win10哪個版本最好用?
如何縮短筆記本開機時間?
Mac OS X滑鼠操作流暢么?
為什麼國內的軟體很少有OS X平台的?

TAG:Python | MicrosoftWindows | 清理电脑 |