Python如何对gzip压缩文件执行内存映射(mmap)操作
错误原因
你原有代码的逻辑顺序存在问题:
gzip.open()返回的是封装了解压逻辑的上层文件对象,调用它的fileno()方法拿到的是原始压缩文件的操作系统文件描述符,直接mmap这个描述符得到的是未解压的原始gzip二进制内容,所以输出会出现gzip文件的标识魔术头b'\x1f\x8b'- mmap是作用于磁盘文件原始字节层面的操作,本身不会自动处理gzip解压逻辑,你之前移除mmap后能拿到正确结果,是gzip模块自动完成了「读原始压缩字节+解压」的流程。
正确实现方案
正确的执行顺序是先对原始压缩文件做内存映射,再把mmap对象交给gzip模块完成解压,mmap对象本身实现了类文件接口,可以直接传入gzip.GzipFile的fileobj参数使用:
import gzip import mmap # 先打开原始压缩文件,做内存映射 with open("/home/test.json.gz", mode="rb") as raw_file: with mmap.mmap(raw_file.fileno(), length=0, access=mmap.ACCESS_READ) as mmap_obj: # 将mmap对象传给GzipFile做解压处理 with gzip.GzipFile(fileobj=mmap_obj, mode="rb") as unzip_file: # 此处读取的就是解压后的正常内容 print(unzip_file.read())
额外说明
- 该方案适合大体积gzip文件的读取场景,mmap减少了内核态到用户态的内存拷贝开销,比普通读文件再解压的I/O性能更高
- 如果不需要一次性读取全量内容,可以直接对
unzip_file做逐行迭代,不需要把全部解压结果加载到内存,内存占用更低 - Windows平台的mmap构造参数和Unix存在少量差异,跨平台使用时可根据官方文档调整对应参数适配
内容的提问来源于stack exchange,提问作者skp
相关产品推荐
相关产品推荐

