用Python刪除本地目錄下某一時間點之前創建的所有文件


因為工作原因,需要定期清理某個文件夾下面創建時間超過1年的所有文件,所以今天集中學習了一下Python對於本地文件及文件夾的操作。網上 這篇文章 簡明扼要地整理出最常見的os方法,抄襲如下:

  • os.listdir(dirname):列出dirname下的目錄和文件
  • os.getcwd():獲得當前工作目錄
  • os.curdir:返回當前目錄('.')
  • os.chdir(dirname):改變工作目錄到dirname
  • os.path.isdir(name):判斷name是不是一個目錄,name不是目錄就返回false
  • os.path.isfile(name):判斷name是不是一個文件,不存在name也返回false
  • os.path.exists(name):判斷是否存在文件或目錄name
  • os.path.getsize(name):獲得文件大小,如果name是目錄返回0L
  • os.path.abspath(name):獲得絕對路徑
  • os.path.normpath(path):規范path字符串形式
  • os.path.split(name):分割文件名與目錄(事實上,如果你完全使用目錄,它也會將最后一個目錄作為文件名而分離,同時它不會判斷文件或目錄是否存在)
  • os.path.splitext():分離文件名與擴展名
  • os.path.join(path,name):連接目錄與文件名或目錄
  • os.path.basename(path):返回文件名
  • os.path.dirname(path):返回文件路徑
  • os.remove(dir) #dir為要刪除的文件夾或者文件路徑
  • os.rmdir(path) #path要刪除的目錄的路徑。需要說明的是,使用os.rmdir刪除的目錄必須為空目錄,否則函數出錯。
  • os.path.getmtime(name) #獲取文件的修改時間
  • os.stat(path).st_mtime#獲取文件的修改時間
  • os.stat(path).st_ctime #獲取文件修改時間
  • os.path.getctime(name)#獲取文件的創建時間

於是我照着這些方法,費半天勁,終於寫出了“清理某路徑下所有文件及文件夾”的方法,代碼如下:

 1 import os
 2 
 3 dirToBeEmptied = 'D:\_Data\Python\os' #需要清空的文件夾
 4 
 5 ds = list(os.walk(dirToBeEmptied)) #獲得所有文件夾的信息列表
 6 dsr = ds[::-1] #反轉該列表,從最底層的文件夾開始清算
 7 
 8 for d in dsr: #遍歷該列表
 9     print(d) #打印出列表項,觀察規律
10     if d[2] != []: #如果該路徑下有文件
11         for x in d[2]: #先將文件清理干凈
12             os.remove(os.path.join(d[0], x))
13 for d in dsr: #再次遍歷該列表
14     if d[1] != []: #如果該路徑下有子文件夾
15         for y in d[1]: #將子文件夾清理干凈
16             os.rmdir(os.path.join(d[0], y))

之所以這么麻煩,是因為 os.rmdir() 有個毛病,只能刪除“空”文件夾。所以只能從最底層的文件夾開始清理,一級一級往上,才能清干凈。

后來想想,應該有更簡便的方法,因為清空文件夾是很常見的動作。查了Python官方文檔,發現了os以外的另一個模塊:shutil(高級文件操作),竟然有 shutil.rmtree() 的方法,不僅是清空,直接連文件夾都一起刪掉,太凶殘了!

為了“僅僅清空”,我搭配使用 shutil 模塊重寫了代碼:

1 import shutil, os
2 
3 os.chdir('d:\_data\python\os') #進入要清空的目錄
4 ds = list(os.listdir()) #獲得該目錄下所有文件或文件夾列表
5 for d in ds: #遍歷該列表
6     if os.path.isfile(d): #如果列表項是文件
7         os.remove(d) #直接刪除
8     else: #如果不是文件,肯定是文件夾
9         shutil.rmtree(d) #也直接刪除

這下可就簡潔多了。

不過,清空一時爽,但已經偏離我原來的目的了:我只是想刪除過期的文件,但文件夾和所有子文件夾都得留着啊。倒也不難,最開始的代碼中,第1次遍歷列表就是只刪文件、不刪文件夾。只要再加個判斷語句,判斷出文件是否過期,就能達到目的了。

我要刪除的文件,實際上是做鏡像備份時,將已從主機刪除或更改的文件暫時保存下來,以備恢復之用。這些文件久了會越來越占空間,因此設定為1年過期。這些文件有一個特點,就是只會被復制過來一次,且不會有任何修改,因此只需要判斷其創建日期就可以。

想着是容易,但萬萬沒想到,Python對時間的處理這么復雜!涉及到兩個模塊:datetimetime。有時間必須重頭系統學習一下,但這里,我只關心現在需要的幾個方法:

  • datetime.datetime.now() #獲取當前時間,返回值的格式類似 datetime.datetime(2017, 12, 14, 1, 29, 24, 406538)
  • datetime.timedelta() #設定兩個時間之間的間隔,用於時間計算,可以設置的單位包括:(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0),默認都為0
  • os.path.getctime() #獲取文件的創建時間,返回值的格式為一個巨大的浮點數,為1970年1月1日到這個創建時間所歷經的秒數
  • datetime.datetime.fromtimestamp() #將os.path.getctime() 轉換為跟datetime.datetime.now()一樣的格式,以進行比較計算

弄清楚上面這些亂七八糟的之后,就可以寫代碼了:

 1 import os, datetime
 2 
 3 dirToBeEmptied = 'D:\_Data\Python\os' #需要清空的文件夾
 4 
 5 ds = list(os.walk(dirToBeEmptied)) #獲得所有文件夾的信息列表
 6 delta = datetime.timedelta(days=365) #設定365天前的文件為過期
 7 now = datetime.datetime.now() #獲取當前時間
 8 
 9 for d in ds: #遍歷該列表
10     os.chdir(d[0]) #進入本級路徑,防止找不到文件而報錯
11     if d[2] != []: #如果該路徑下有文件
12         for x in d[2]: #遍歷這些文件
13             ctime = datetime.datetime.fromtimestamp(os.path.getctime(x)) #獲取文件創建時間
14             if ctime < (now-delta): #若創建於delta天前
15                 os.remove(x) #則刪掉

呼~~~~~~~~~

真夠復雜的!不知道有沒有簡便一點的辦法……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM