網頁

2021年1月29日 星期五

Python:依檔案清單大量找檔案並拷貝

有一個檔案清單紀錄要找尋在 dir 目錄下的檔案,並將找到的檔案拷貝到桌面 tmp目錄下,
找尋的目錄dir,目錄下有多層目錄共38006個檔案(沒有順序)。

方法1】:
讀取檔案清單,依清單第一筆資料遞迴搜尋目錄檔名是否符合,然後清單第二筆再遞迴搜尋目錄檔名是否符合 . . . 直到清單最後一筆。
程式碼:https://ideone.com/NSdqT4

圖示範例:


所花費時間 (約3.05s):
 

方法2 】
讀取檔案清單存放在Dictionary,遞迴目錄的每一檔案名稱是否是 dict 的 key 值。
程式碼:https://ideone.com/eN5xXP

圖示範例:

 
所花費時間 (約0.75s):






由此看來遍歷目錄的檔案然後判斷是否在Dict 中的 key值(Hash Map)是比每一筆資料都要去遍歷目錄樹一次效率要好得多,當清單的數量多的時候差異會更大。

程式碼 :
import os, re, shutil, sys, time
if len(sys.argv) == 1 or len(sys.argv) == 2:
    lst_file = 'list2.txt' #欲搜尋檔案清單
    search_dir = "./dir"   #搜尋目錄
else:
    lst_file = sys.argv[1]
    search_dir = sys.argv[2]
start = time.time()
tag_dir = os.path.expandvars('$HOME') + "/Desktop/tmp/" #目標目錄
dict = {} #建立Hach map
with open(lst_file) as f:
    for line in f.readlines():
        line = line[:-1]
        dict[line] = 0
num_files = 0 #計算檔案數量變數
if not os.path.isdir(tag_dir): #測試目標目錄存在否
    os.mkdir(tag_dir)
#遞迴目錄樹
for dirPath, dirNames, fileNames in os.walk(search_dir):
    for f in fileNames:
        num_files += 1
        basename = os.path.splitext(f)[0]
        if basename in dict: #如果檔名與hash key相同
            print "finded >>", os.path.join(dirPath, f)
            old = os.path.join(dirPath, f)
            new = tag_dir + f
            shutil.copy(old, new) #複製檔案到目標目錄
print "Total search files:", num_files
end = time.time()
print "Elapsed time:", end - start


沒有留言:

張貼留言