python3 读写大文件
python3 读写大文件
import os
file_path = "/home/Qwen3-Embedding-0.6B_external.mlir"
from functools import partial, wraps
from typing import TextIO, Callable
def chunked_file_reader(fp: TextIO, block_size: int=1024 * 8):
for chunk in iter(partial(fp.read, block_size), ''):
yield chunk
def read_file(file_path: str) -> int:
count: int = 0
with open(file_path) as f_read:
for chunk in chunked_file_reader(f_read):
count += 1
# if(581500 <= count <= 581800):
# if(581500 <= count):
# print(chunk)
# if("tensor<3844x1xf16>" in chunk and "stc.matmul" in chunk):
if("matmul" in chunk):
print(chunk)
# Remove this break to read the entire file
return count
if __name__ == "__main__":
if os.path.exists(file_path):
print(f"File {file_path} exists, reading...")
count = read_file(file_path)
print(f"Total chunks read: {count}")
else:
print(f"File {file_path} does not exist.")
在代码
def chunked_file_reader(fp: TextIO, block_size: int=1024 * 8):
中,block_size 参数定义了 每次从文件中读取的字节数,它是文件分块处理的核心控制参数。
1. block_size 的技术定义
作用:指定每次调用 fp.read() 时读取的最大字节数。
默认值:1024 * 8(即8KB),这是一个经验值,平衡了内存效率和I/O性能。
单位:字节(Bytes)。
2. 工作原理
for chunk in iter(partial(fp.read, block_size), ''):
yield chunk
fp.read(block_size):
每次从文件对象 fp 中读取最多 block_size 字节的数据。
iter + partial:组合使用,持续读取直到返回空字符串('',表示文件结束)。
生成器:通过 yield 逐块返回数据,避免一次性加载整个文件。
3. 为什么需要分块?
| 场景 | 不分块的问题 | 分块的优点 |
|---|---|---|
| 大文件处理(如GB级日志) | 内存爆满(OOM) | 固定内存占用(仅 block_size 大小) |
| 网络传输 | 延迟高,吞吐不稳定 | 平滑数据流,减少延迟峰值 |
| 实时处理 | 必须等待整个文件加载完毕 | 边读取边处理 |
4. block_size 的取值建议
| 取值 | 适用场景 | 注意事项 |
|---|---|---|
| 1KB~8KB | 常规文本文件(如日志、CSV) | 默认值通常是安全的选择 |
| 64KB~1MB | 二进制文件(如图片、视频) | 需测试内存与IPS(每秒操作数)的平衡 |
| <1KB | 内存极度受限环境(嵌入式) | 可能增加I/O开销 |
6. 与其他参数的协同
文件系统块大小:通常为4KB(SSD)或1KB(HDD),匹配 block_size 可减少物理I/O次数。
磁盘缓存:大于缓存大小时(如Linux默认30%内存),分块读取仍能避免内存压力。
7. 实际应用示例
案例1:逐块处理大CSV
import csv
def process_large_csv(file_path):
with open(file_path, 'r') as fp:
reader = csv.reader(chunked_file_reader(fp, block_size=8192))
for row in reader:
process(row) # 假设的逐行处理函数
案例2:HTTP分块上传
import requests
def upload_large_file(url, file_path):
with open(file_path, 'rb') as fp:
for chunk in chunked_file_reader(fp, block_size=64*1024):
requests.post(url, data=chunk)
总结
block_size 是 内存效率 和 I/O效率 的权衡参数:
较小值:内存友好,但可能增加I/O次数。
较大值:减少I/O次数,但占用更多内存。
推荐实践:
默认使用 8KB(尤其文本处理)。
对二进制文件可尝试 64KB~1MB。
在资源受限环境中测试后调整。

浙公网安备 33010602011771号