
本文介绍如何使用 tqdm 库构建自定义文件读取器,在 python 文件 io 过程中实时显示读取进度与瞬时/平均读取速度(如 bytes/s),特别适用于对比网络盘与本地磁盘的 i/o 性能。
本文介绍如何使用 tqdm 库构建自定义文件读取器,在 python 文件 io 过程中实时显示读取进度与瞬时/平均读取速度(如 bytes/s),特别适用于对比网络盘与本地磁盘的 i/o 性能。
在进行跨存储介质(如网络共享驱动器 vs 本地 SSD)的文件读取性能评估时,仅靠总耗时难以反映真实吞吐表现。更专业的方式是实时监控读取速率——包括已读字节数、剩余时间预估、以及关键指标:平均速度(bytes/s)和瞬时速度(bytes/s)。Python 原生 open() 不提供此类反馈,但借助成熟的第三方库 tqdm,我们可轻松实现“带速读”的文件流封装。
核心思路是:创建一个包装类(如 TQDMFileReader),它持有原始文件对象,并重写 read() 方法——每次读取后,立即将实际读取的字节数提交给 tqdm 实例更新进度条与速率计算。
以下为完整、健壮的实现:
import os
from tqdm import tqdm
class TQDMFileReader:
def __init__(self, file_obj, desc="Reading", unit="B", unit_scale=True):
self.file = file_obj
# 自动获取文件大小(需支持 fileno(),对普通文件有效)
try:
total_size = os.stat(file_obj.fileno()).st_size
except (OSError, AttributeError):
total_size = None # 若无法获取大小(如 stdin、管道),设为 None,tqdm 自动切换为无长度模式
self.tqdm = tqdm(
total=total_size,
desc=desc,
unit=unit,
unit_scale=unit_scale,
leave=True,
dynamic_ncols=True
)
def read(self, size=-1):
data = self.file.read(size)
self.tqdm.update(len(data))
return data
def close(self):
self.tqdm.close()
self.file.close()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()使用示例如下(推荐配合 with 语句确保资源释放):
立即学习“Python免费学习笔记(深入)”;
# 测量网络路径文件读取速度(替换为你的实际路径)
file_path = r"\serversharelarge_file.bin" # Windows 网络路径
# 或 file_path = "/mnt/nfs/share/large_file.bin" # Linux NFS 路径
with open(file_path, "rb") as f:
with TQDMFileReader(f, desc="Network Read") as reader:
while True:
chunk = reader.read(8192) # 每次读取 8KB
if not chunk:
break
# 在此处处理数据(如校验、解密、写入本地等)
# process(chunk)✅ 输出效果示例:
Network Read: 100%|██████████| 1.23G/1.23G [02:15<br> 其中 <code>9.25MB/s是当前平均速率,[02:15 表示已用时与预估剩余时间。
⚠️ 注意事项:
-
tqdm的速率统计基于累计时间与总字节数,对小文件或极短读取可能不够稳定,建议测试 ≥100MB 文件以获得可靠参考; - 网络驱动器受协议(SMB/NFS)、缓存策略、服务端负载影响显著,建议多次运行取中位数;
- 若文件大小不可知(如流式响应),
tqdm(total=None)仍可显示瞬时速率(rate),但无进度百分比; - 避免在
read()中混用其他 I/O 操作(如seek()),否则会干扰tqdm的字节计数逻辑; - 如需同时对比本地与网络读取,可分别运行两次并记录
tqdm输出中的最终速率值,或通过reader.tqdm.format_dict提取结构化数据用于自动化分析。
通过该方案,你不再需要手动计时 + 字节累加,即可获得专业级的交互式 I/O 性能视图,为存储选型与系统调优提供直观依据。


















