改完文件名稱後,Dr.he 發現分別保存5個狀態的jpg 文件的文件夾出現缺少文件的情況。爲了讓他少熬夜查找缺失文件,結合網友分享的腳本,寫了查找以下代碼,滿足他的需求,同時備忘。以下代碼能解決實際需求,適合初學者。不足之處,歡迎指出修正!
寫這篇文章前,以爲方法和函數一樣的,若同樣有此困惑的網友可參考:https://www.cnblogs.com/mayugang/p/9977914.html
方法解析:
standard_directory() 函數用於輸入要檢索的文件夾路徑,共有5次機會,期間可以輸入‘#’退出程序。路徑要符合以下條件:
- 路徑層級只能用正斜槓‘/’表示,不能包含反斜槓‘\’;
- 不能是文件路徑;
- 文件夾目錄不能包含文件;
- 其他的情況不允許的情況,例如路徑不存在。
standard_file(folder_dir) 函數用於輸入記錄檢索結果的文件路徑,共有5次機會,期間可以輸入‘#’退出程序。路徑要符合以下條件:
- 路徑層級只能用正斜槓‘/’表示,不能包含反斜槓‘\’;
- 不能是文件夾路徑;
- 文件路徑的上級目錄不能是要檢索的文件夾路徑folder_dir;
- 輸入不存在的文件路徑:其上級目錄不能是要檢索的文件夾路徑folder_dir,不能是不存在文件夾路徑。
input_directory() 函數調用了standard_directory()、standard_file(folder_dir) ,輸入文件夾和文件路徑,分別返回這兩個路徑;
max_files_directory(src_directory) 函數根據文件夾路徑查找文件名稱是14個字符的文件數量最多的文件夾路徑作爲參考目錄,就是這個文件夾爲準,查找不在此文件夾中的文件。返回文件最多的文件夾目錄
max_file_index、文件夾列表的大小file_folder_count、參考目錄的文件列表max_file_folder_dir。
find_missing_file() 函數調用了input_directory()、max_files_directory(src_directory),查找目標目錄的文件是否缺少參考目錄的文件,記錄下缺少的文件到結果文件中。
1 import os 2 import datetime 3 4 5 def standard_directory(): 6 pass_status = False # 目錄輸入通過的狀態,初始不通過 7 inp_limit = 5 # 輸入限制次數 8 warn_str = "請輸入要檢索的文件夾完整路徑(如C:/Users/Default/Pictures),退出請按’#‘:" 9 for inp_count in range(inp_limit): 10 pass_status = True # 目錄輸入通過的狀態,布爾類型 11 inp_path = input("文件夾路徑輸入限制{}次,第{}次\n".format(inp_limit, inp_count + 1) + warn_str) 12 if '\\' in inp_path or '/' not in inp_path: 13 if inp_path == '#': 14 exit() # 退出程序 15 print("輸入的文件夾路徑格式有誤,路徑層級只能用正斜槓‘/’表示\n") 16 pass_status = False 17 elif os.path.isfile(inp_path): 18 print("輸入路徑是文件格式,路徑只能是文件夾的目錄\n") 19 pass_status = False 20 elif os.path.isdir(inp_path): 21 count = 0 # 記錄文件的數量 22 for folder in os.listdir(inp_path): 23 if '.' in folder: 24 count += 1 # 記錄文件的數量 25 if count > 0: 26 print("輸入的路徑中包含文件,路徑中只能有文件夾\n") 27 pass_status = False 28 # 當路徑不存在 29 else: 30 print("輸入文件夾路徑不存在或存在未知錯誤,請檢查\n") 31 pass_status = False 32 if pass_status: 33 return inp_path 34 if not pass_status: 35 print("{}次輸入檢索的文件夾路徑有誤,程序退出".format(inp_limit)) 36 exit() # 路徑輸入錯誤,退出程序 37 38 39 def standard_file(folder_dir): 40 pass_status = False # 目錄輸入通過的狀態,初始不通過 41 inp_limit = 5 # 輸入限制次數 42 warn_str = "請輸入記錄結果的文件完整路徑(如C:/Users/Default/Pictures/log.txt),退出請按’#‘:" 43 for inp_count in range(inp_limit): 44 pass_status = True # 目錄輸入通過的狀態,布爾類型 45 inp_path = input("文件夾路徑輸入限制{}次,第{}次\n".format(inp_limit, inp_count + 1) + warn_str) 46 if '\\' in inp_path or '/' not in inp_path: 47 if inp_path == '#': 48 exit() # 退出程序 49 print("輸入的文件路徑格式有誤,路徑層級只能用正斜槓‘/’表示\n") 50 pass_status = False 51 elif os.path.isdir(inp_path): # 若輸入的是存在的文件夾路徑 52 print("輸入的文件路徑格式有誤,路徑是文件夾路徑\n") 53 pass_status = False 54 elif os.path.isfile(inp_path): 55 parent_path = os.path.dirname(inp_path) 56 if parent_path == folder_dir: 57 print("記錄結果的文件不能在要檢索的文件夾路徑中:{}\n".format(folder_dir)) 58 pass_status = False 59 continue 60 elif not os.path.exists(inp_path): # 若輸入的是不存在的文件或文件夾 61 # 若輸入的路徑包含逗號‘.’ 62 if '.' in inp_path: 63 parent_path = os.path.dirname(inp_path) # 獲取文件的上級目錄 64 if not os.path.exists(parent_path): # 文件的上級目錄不存在 65 print("輸入文件的上級目錄不存在\n") 66 pass_status = False 67 elif parent_path == folder_dir: # 文件的上級目錄不能是要檢索的文件夾路徑 68 print("記錄結果的文件不能在要檢索的文件夾路徑中:{}".format(folder_dir)) 69 pass_status = False 70 else: 71 # 若是文件則要判斷,文件上級路徑是否存在 72 print("輸入的文件路徑存在未知") 73 pass_status = False 74 if pass_status: 75 return inp_path 76 if not pass_status: 77 print("{}次輸入記錄結果的文件完整路徑有誤,程序退出".format(inp_limit)) 78 exit() # 路徑輸入錯誤,退出程序 79 80 81 def input_directory(): 82 src_path = standard_directory() 83 print("\n") 84 res_path = standard_file(src_path) 85 return src_path, res_path 86 87 88 def max_files_directory(src_directory): 89 file_folders = os.listdir(src_directory) # 文件夾名稱列表 90 file_folder_count = len(file_folders) # 傳參的文件夾中文件夾的數量 91 file_num_list = [] # 定義文件數量列表,賦值空列表 92 # 查找文件最多的目錄(文件夾)作爲參照目錄 93 for folder in file_folders: 94 count = 0 # 記錄文件名稱是14個字符的文件數量 95 file_list = os.listdir(src_directory + "/" + folder) # 文件夾中的文件列表 96 # 查找包括後綴名的文件名稱是14個字符 97 for file in file_list: 98 if len(file) == 14: 99 count += 1 # 記錄文件名稱長度符合的文件數量 100 file_num_list.append(count) # 將文件數量增加到件數量列表的後面 101 # file_num = len(file_list) # 獲取文件夾中的文件數量 102 # file_num_list.append(file_num) # 將文件數量增加到件數量列表的後面 103 max_file_index = file_num_list.index(max(file_num_list)) # 查找文件列表中文件數量最大的索引 104 # 文件名符合條件的文件數量最多的文件夾是參照目錄,其餘文件夾的文件與參照目錄的文件比較不同 105 max_file_folder_dir = src_directory + "/" + file_folders[max_file_index] 106 # 返回形參目錄的文件最多的文件夾目錄,文件夾列表的大小,參考目錄的文件列表 107 return max_file_index, file_folder_count, max_file_folder_dir 108 109 110 # 查找目標目錄的文件是否缺少參考目錄的文件,記錄下缺少的文件到結果文件中 111 def find_missing_file(): 112 # 返回要對比文件夾目錄、記錄結果的文件路徑 113 src_directory, log_path = input_directory() 114 115 # 返回實參目錄的文件最多的文件夾索引、實參目錄的文件夾列表的大小,實參目錄中參考目錄 116 max_file_index, file_folder_count, max_file_folder_dir = max_files_directory(src_directory) 117 refer_file_names = os.listdir(max_file_folder_dir) # 參照目錄下的文件列表 118 print("\n輸入的目錄中文件最多的文件夾索引:{},輸入的目錄中文件夾列表的大小:{},作爲參考的文件夾路徑:{}\n參考目錄的文件列表:{}\n" 119 .format(max_file_index, file_folder_count, max_file_folder_dir, refer_file_names)) 120 121 # 獲取當前日期和時間,將時間轉爲字符串 122 now_time = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') 123 # 以讀/寫 追加的模式打開文件 124 write_file = open(log_path, 'a+') 125 # 以追加的模式寫入當前日期和時間 126 write_file.write(now_time + "\n") 127 # 以追加的模式寫入參照目錄 128 write_file.write("參考目錄:" + max_file_folder_dir + "\n") 129 # 循環目錄的文件列表 130 for i in range(file_folder_count): 131 # 當索引等於有最多文件的文件夾(參考文件夾)索引,跳出當前循環 132 if i == max_file_index: 133 print("第{}個文件夾是參考目錄:{}".format(i + 1, os.listdir(src_directory)[i])) 134 continue 135 136 count = 0 # 記錄與參照文件夾的文件不同的數量 137 # 目的文件夾(非參考文件夾)的文件 138 target_path = src_directory + "/" + os.listdir(src_directory)[i] 139 target_file_names = os.listdir(target_path) 140 print("第{}個文件夾的路徑{}\n文件夾的文件列表:{}\n".format(i + 1, target_path, target_file_names)) 141 142 for name in refer_file_names: 143 if len(name) == 14: 144 if name not in target_file_names: 145 write_file.write(name + "\n") # 將在參照目錄的文件卻不在目的文件夾(非參照文件夾)的文件,寫入文件 146 count += 1 # 記錄與參照文件夾的文件不同的數量 147 write_file.write(target_path + " 缺少的文件數目:" + str(count) + "\n\n") 148 149 write_file.close() # 關閉文件 150 151 152 # Python 內置的系統變量 __name__用於標識所在模塊的模塊名 153 # if __name__ == '__main__': 的作用是確保只有單獨運行該模塊時,此表達式才成立,纔可以進入此判斷語法,執行其中的測試代碼 154 if __name__ == '__main__': 155 find_missing_file()