[英]fast folder size calculation in Python on Windows
我正在尋找一種快速計算Windows上Python文件夾大小的方法。 這是我到目前為止:
def get_dir_size(path):
total_size = 0
if platform.system() == 'Windows':
try:
items = win32file.FindFilesW(path + '\\*')
except Exception, err:
return 0
# Add the size or perform recursion on folders.
for item in items:
attr = item[0]
name = item[-2]
size = item[5]
if (attr & win32con.FILE_ATTRIBUTE_DIRECTORY) and \
not (attr & win32con.FILE_ATTRIBUTE_SYSTEM): # skip system dirs
if name not in DIR_EXCLUDES:
total_size += get_dir_size("%s\\%s" % (path, name))
total_size += size
return total_size
當文件夾大小超過100G時,這還不夠好。 任何想法如何改進它?
在一台快速機器(2Ghz + - 5G內存)上,在226,001個文件和12,043個文件夾中花了72秒超過422GB。 使用資源管理器屬性選項需要40秒。
我知道我有點貪心,但我希望有更好的解決方案。
勞倫特盧斯
快速分析代碼表明,僅在FindFilesW()
調用中就消耗了90%以上的時間。 這意味着通過調整Python代碼進行的任何改進都是次要的。
微小的調整(如果你堅持使用FindFilesW)可以包括確保DIR_EXCLUDES是一個集合而不是列表,避免在其他模塊上重復查找,並且懶惰地索引到item [],以及在外部移動sys.platform檢查。 這包含了這些變化和其他變化, 但它不會提供超過1-2%的加速 。
DIR_EXCLUDES = set(['.', '..'])
MASK = win32con.FILE_ATTRIBUTE_DIRECTORY | win32con.FILE_ATTRIBUTE_SYSTEM
REQUIRED = win32con.FILE_ATTRIBUTE_DIRECTORY
FindFilesW = win32file.FindFilesW
def get_dir_size(path):
total_size = 0
try:
items = FindFilesW(path + r'\*')
except pywintypes.error, ex:
return total_size
for item in items:
total_size += item[5]
if (item[0] & MASK == REQUIRED):
name = item[8]
if name not in DIR_EXCLUDES:
total_size += get_dir_size(path + '\\' + name)
return total_size
唯一顯着的加速將來自使用不同的API或不同的技術。 您在后台執行此操作的評論中提到過,因此您可以使用其中一個程序包對其進行增量更新,以監控文件夾中的更改。 可能是FindFirstChangeNotification API或類似的東西。 您可以設置監視整個樹,或者根據該例程的工作方式(我沒有使用它),您可能最好在整個樹的各個子集上注冊多個請求,如果這樣可以減少您的搜索量做(通知時)以確定實際改變的內容和現在的大小。
編輯:我在評論中詢問您是否考慮了Windows XP及更高版本所做的繁重的文件系統元數據緩存。 我剛剛檢查了你的代碼(和我的)對Windows本身的性能,選擇我的C:\\文件夾中的所有項目,然后按Alt-Enter打開屬性窗口。 在完成這一次(使用你的代碼)並獲得40秒后,我現在從這兩種方法中消耗了20秒。 換句話說, 你的代碼實際上和Windows本身一樣快 ,至少在我的機器上。
如果使用os.walk,則不需要使用遞歸算法。 請檢查這個問題 。
你應該花時間兩種方法,但這應該更快:
import os
def get_dir_size(root):
size = 0
for path, dirs, files in os.walk(root):
for f in files:
size += os.path.getsize( os.path.join( path, f ) )
return size
我目前沒有要測試的Windows框,但文檔指出win32file.FindFilesIterator
“類似於win32file.FindFiles
,但是避免為巨大的目錄創建列表”。 這有幫助嗎?
這是一個目錄樹的巨大。 正如其他人所說,我不確定你是否可以加快速度......不像那樣,冷酷無數據。 這意味着...
如果您可以以某種方式緩存數據(不確定實際含義是什么),那么您可以加快速度(我認為......一如既往地衡量,衡量,衡量)。
我不認為我必須告訴你如何進行緩存,我想,你似乎是一個知識淵博的人。 而且無論如何我都不會知道Windows的袖口。 ;-)
這突然襲來我:
try:
items = win32file.FindFilesW(path + '\\*')
except Exception, err:
return 0
異常處理可以為您的算法增加大量時間。 如果您可以以一種您總是知道安全的方式指定路徑,從而防止需要捕獲異常(例如,在查找該文件夾中的文件之前首先檢查給定路徑是否為文件夾),您可以找到一個顯着的加速。
# Size of File Folder/Directory in MBytes
import os
# pick a folder you have ...
folder = 'D:\\zz1'
folder_size = 0
for (path, dirs, files) in os.walk(folder):
for file in files:
filename = os.path.join(path, file)
folder_size += os.path.getsize(filename)
print "Folder = %0.1f MB" % (folder_size/(1024*1024.0))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.