如何为Python zipfile代码添加进度条?含多线程及压缩耗时测量需求
为zipfile添加进度条并测量压缩时长
添加进度条(解决TQDM无效问题)
zipfile模块的write()方法没有提供进度回调接口,直接用TQDM无法跟踪压缩进度。我们需要通过自定义带进度跟踪的文件读取类,配合writestr()方法来实现进度条:
实现代码
import zipfile import tqdm import os import time import io class ProgressReader(io.BufferedReader): def __init__(self, file_obj, progress_bar): super().__init__(file_obj) self.progress_bar = progress_bar def read(self, size=-1): chunk = super().read(size) if chunk: self.progress_bar.update(len(chunk)) return chunk def compress_file(zip_name, source_path): # 获取源文件大小,作为进度条总长度 total_size = os.path.getsize(source_path) # 初始化TQDM进度条,lock参数保证多线程下输出不混乱 with tqdm.tqdm( total=total_size, unit="B", unit_scale=True, desc="压缩进度", lock=True ) as pbar: with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_LZMA) as zf: file_name_in_zip = os.path.basename(source_path) with open(source_path, 'rb') as f: # 使用自定义的ProgressReader跟踪读取进度 progress_reader = ProgressReader(f, pbar) zf.writestr(file_name_in_zip, progress_reader.read()) # 压缩完成后删除源文件 os.remove(source_path)
核心逻辑说明
- 自定义的
ProgressReader会在每次读取文件块时更新TQDM进度条 - 用
writestr()替代write(),让我们可以介入文件读取过程,捕获进度数据 lock=True确保多线程环境下进度条输出不会混乱
测量压缩时长
用time.perf_counter()记录压缩前后的时间戳,差值就是压缩耗时(该方法比time.time()更适合测量短时间间隔):
代码示例
# 在调用压缩函数前后记录时间 start_time = time.perf_counter() compress_file("target.zip", f"{self.dir}\\{new_archive}") end_time = time.perf_counter() # 输出耗时 print(f"压缩总耗时: {end_time - start_time:.2f} 秒")
注意事项
- 若线程包含其他逻辑,确保只统计压缩代码段的时间,不要包含线程启动、大文件删除等额外操作
- 多次运行取平均值可得到更准确的耗时数据
内容的提问来源于stack exchange,提问作者user20012049
相关产品推荐
相关产品推荐

