本文目录导读:

- 使用
with和for循环逐行读取(最推荐) - 使用
readline()手动控制 - 分块读取(适用于二进制文件或非行式数据)
- 使用
pandas分块读取(CSV/Excel等表格数据) - 使用
linecache随机访问大文件 - 使用
mmap内存映射(适合高性能场景) - 实际案例:处理10GB日志文件
- 性能对比与选择建议
- 注意事项
在Python中读取大文件时,关键是要避免一次性将整个文件加载到内存,以下是几种常用且高效的方法:
使用 with 和 for 循环逐行读取(最推荐)
这是最经典且内存友好的方式,Python会自动缓冲读取,每次只加载一行到内存。
# 逐行读取,适合处理文本文件
with open('large_file.txt', 'r', encoding='utf-8') as f:
for line in f:
# 处理每一行数据
process_line(line.strip())
优点:内存占用极低,代码简洁 适用场景:日志文件、CSV、JSONL等行式数据
使用 readline() 手动控制
当需要在读取过程中进行复杂判断时,可以有选择地读取。
with open('large_file.txt', 'r') as f:
while True:
line = f.readline()
if not line:
break
# 处理行数据
process_line(line)
分块读取(适用于二进制文件或非行式数据)
对于图片、视频、压缩文件等,可以按固定大小(如8KB)分块读取。
def read_in_chunks(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
# 使用示例
for chunk in read_in_chunks('large_video.mp4'):
process_chunk(chunk)
使用 pandas 分块读取(CSV/Excel等表格数据)
Pandas提供了 chunksize 参数,非常适合结构化表格数据。
import pandas as pd
# 每次读取1000行
chunk_reader = pd.read_csv('large_data.csv', chunksize=1000)
for chunk in chunk_reader:
# 处理每个数据块(chunk是一个DataFrame)
process_chunk(chunk)
使用 linecache 随机访问大文件
如果只需要访问文件中的特定行,而不需要按顺序读取:
import linecache
# 读取第100行(注意:行号从1开始)
line = linecache.getline('large_file.txt', 100)
print(line)
# 清理缓存(处理完文件后建议执行)
linecache.clearcache()
使用 mmap 内存映射(适合高性能场景)
内存映射将文件映射到虚拟内存地址空间,由操作系统管理页面加载。
import mmap
with open('large_file.txt', 'r+b') as f:
# 创建内存映射
with mmap.mmap(f.fileno(), 0) as mmapped_file:
# 按行迭代(使用内存映射的find方法)
start = 0
while True:
end = mmapped_file.find(b'\n', start)
if end == -1:
break
line = mmapped_file[start:end]
process_line(line)
start = end + 1
实际案例:处理10GB日志文件
假设有一个10GB的访问日志文件,需要统计每种HTTP状态码出现的次数:
from collections import Counter
def process_large_log(file_path):
status_counter = Counter()
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
# 假设日志格式:IP - - [date] "GET /url HTTP/1.1" 200 1234
parts = line.split()
if len(parts) >= 8:
status_code = parts[7]
status_counter[status_code] += 1
return status_counter
# 使用(内存占用稳定在几MB)
result = process_large_log('access.log.10gb')
print(result.most_common(10))
性能对比与选择建议
| 方法 | 内存占用 | 读取速度 | 适用场景 |
|---|---|---|---|
for line in f |
极低 | 快 | 文本文件,90%场景 |
分块读取(read) |
可控 | 快 | 二进制文件、非行式 |
| Pandas chunksize | 中等 | 中等 | 结构化表格数据 |
| mmap | 中等 | 极快 | 需要随机访问、高性能 |
注意事项
- 编码问题:大文件常见UTF-8,但遇到GBK等编码需指定
encoding='gbk' - 换行符:Windows的
\r\n和Linux的\n,Python会自动处理 - 关闭文件:使用
with语句会自动关闭,避免资源泄漏 - 进度显示:处理超大文件时可配合
tqdm显示进度
from tqdm import tqdm
with open('huge_file.txt', 'r') as f:
for line in tqdm(f, desc='处理中', unit='行'):
process_line(line)
对于绝大多数大文件处理场景,使用 with open() as f: for line in f 就足够了,这是Python官方推荐的方式,既简单又高效。