defcheck_files(self): """ 检查文件,遍历unzip_files,与zip_file_dict的key匹配,有找到的放入found_files,没找到的放入not_found """ for file in set(self.unzip_files): # 为预防TXT文件中存在重复文件名,用set集合去重一下 if file in self.zip_file_dict.keys(): for x in self.zip_file_dict[file]: self.found_files.append(x) else: self.not_found.append(file)
这里主要需要考虑存在不同文件夹中出现同名压缩包的情形。分步执行情况:
分成两个列表
实现一个单独解压7z文件的方法
defupzip_file(self, file_full_path): """ 对单个7z文件进行解压缩,解压缩后的文件,放置在原7z文件所在路径下,解压成功后,删除7z文件 :param file_full_path: 需要传入完整的文件路径 :return: True or False """ if is_7zfile(file_full_path): try: start_time = time.time() with SevenZipFile(file_full_path, mode='r') as sevenZ_f: sevenZ_f.extractall(os.path.split(file_full_path)[0]) # 解压到与压缩包相同的目录下 os.remove(file_full_path) # 解压成功后删除文件 end_time = time.time() print(f'解压缩{file_full_path}文件成功,用时{round(end_time-start_time, 4)}秒') except Exception as e: print('Error when uncompress file! info: ', e) returnFalse else: returnTrue else: print('This is not a true 7z file!') returnFalse
这一段是带薪学习的成果了,主要Ctrl C + Ctrl V(^_^感谢万能的百度)。不过其实理解起来也不难,使用了py7zr这个库来解压7z压缩包,先判断是否7z文件,再进行解压,成功返回True,否则False。
进行批量并发解压缩
defrun_unzip(self, max_workers=10): """ 开启多线程进行解压缩 :param max_workers: 开启的最大线程数,默认10个 """ with ThreadPoolExecutor(max_workers=max_workers) as pool: futures = [pool.submit(self.upzip_file, file) for file in self.found_files]
蚂蚁老师的教程(Python并发编程,用多线程加速程序运行)里学(抄)来的。
分步执行情况:
多线程并发解压
输出没有匹配到压缩包的文件名,格式为TXT文件
defwrite_not_found_file(self): """ 当存在没有找到的解压文件时,写入文件,文件存放在与txt_file相同的目录下,命名为not_found_fifle.txt """ if len(self.not_found) > 0: txt_path = self.txt_file.replace('.txt', '_not_found.txt') # 将原TXT文件的完整路径进行修改,增加“_not_found”部分作为输出TXT文件的文件名 with open(txt_path, 'w', encoding='utf-8') as fout: fout.write('\n'.join(self.not_found))
defread_txt_file(self, code='utf-8'): """ 读取TXT文件,生成需要解压的文件list :param code: 读取文件使用的编码格式 """ with open(self.txt_file, 'r', encoding=code) as fin: self.unzip_files = fin.read().split('\n')
defget_all_zip_files(self): """ 使用os.walk模块遍历根目录下的所有7z文件,生成zip_file_dict """ for path, dirnames, filenames in os.walk(self.root_path): for filename in filenames: if filename.endswith('.7z') andnot filename.startswith('~'): self.zip_file_count += 1 full_path = os.path.join(path, filename) filename = filename.replace('.7z', '') if filename in self.zip_file_dict.keys(): self.zip_file_dict[filename].append(full_path) else: self.zip_file_dict[filename] = [full_path]
defcheck_files(self): """ 检查文件,遍历unzip_files,与zip_file_dict的key匹配,有找到的放入found_files,没找到的放入not_found """ for file in set(self.unzip_files): #为预防TXT文件中存在重复的文件名,加个set集合去重 if file in self.zip_file_dict.keys(): for x in self.zip_file_dict[file]: self.found_files.append(x) else: self.not_found.append(file)
defupzip_file(self, file_full_path): """ 对单个7z文件进行解压缩,解压缩后的文件,放置在原7z文件所在路径下,解压成功后,删除7z文件 :param file_full_path: 需要传入完整的文件路径 :return: True or False """ if is_7zfile(file_full_path): try: start_time = time.time() with SevenZipFile(file_full_path, mode='r') as sevenZ_f: sevenZ_f.extractall(os.path.split(file_full_path)[0]) os.remove(file_full_path) end_time = time.time() print(f'解压缩{file_full_path}文件成功,用时{round(end_time-start_time, 4)}秒') except Exception as e: print('Error when uncompress file! info: ', e) returnFalse else: returnTrue else: print('This is not a true 7z file!') returnFalse
defrun_unzip(self, max_workers=10): """ 开启多线程进行解压缩 :param max_workers: 开启的最大线程数,默认10个 """ with ThreadPoolExecutor(max_workers=max_workers) as pool: futures = [pool.submit(self.upzip_file, file) for file in self.found_files]
defwrite_not_found_file(self): """ 当存在没有找到的解压文件时,写入文件,文件存放在与txt_file相同的目录下,命名为not_found_fifle.txt """ if len(self.not_found) > 0: # txt_path = os.path.split(self.txt_file)[0] txt_path = self.txt_file.replace('.txt', '_not_found.txt') with open(txt_path, 'w', encoding='utf-8') as fout: fout.write('\n'.join(self.not_found))