You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python mmap读取Wikidata压缩JSON Dump文件遇错求助

问题分析与解决

两个错误的根源

  1. Unicode解码错误:直接对bz2.open返回的文件对象做mmap是错误的。bz2.open的fileno()对应的是压缩后的原始文件数据流,而非解压后的内容。mmap读取的是压缩字节,而json.loads会尝试把这些压缩字节当成UTF-8文本解码,自然会出现解码错误——这根本不是正常的JSON文本字节。

  2. 循环无法终止:同样因为mmap映射的是压缩文件的全部内容,压缩数据的末尾不会出现空字节串b"",所以iter(mm.readline, b"")永远触发不了终止条件,循环会一直运行。

而不用mmap时能正常读取,是因为bz2.open的readline会自动逐行解压数据,返回正确的JSON字节,但这种流式解压速度确实较慢。

正确的实现方式

核心思路:先把bz2压缩文件解压到一个可随机访问的临时文件,再对这个临时文件做mmap——这样既利用了mmap的快速读取特性,又能拿到正确的解压后数据。

基础实现代码

import bz2
import mmap
import json
import tempfile

def read_file(filename):
    # 创建临时文件存储解压后的内容
    with tempfile.NamedTemporaryFile(mode='wb+', delete=False) as temp_f:
        # 先把bz2文件全部解压到临时文件
        with bz2.open(filename, 'rb') as f:
            temp_f.write(f.read())
        # 重置临时文件指针到开头
        temp_f.seek(0)
        
        # 对临时文件做mmap
        with mmap.mmap(temp_f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
            for line in iter(mm.readline, b""):
                line = line.rstrip(b",\n")
                if line in [b"[", b"]"]:
                    continue
                yield json.loads(line)

优化版(减少磁盘占用)

如果担心临时文件占用过多磁盘空间,可以用SpooledTemporaryFile,当数据量超过阈值时才写入磁盘,否则存在内存中:

import bz2
import mmap
import json
import tempfile

def read_file(filename):
    # max_size设置为100MB,可根据内存情况调整
    with tempfile.SpooledTemporaryFile(mode='wb+', max_size=1024*1024*100) as temp_f:
        with bz2.open(filename, 'rb') as f:
            temp_f.write(f.read())
        temp_f.seek(0)
        
        with mmap.mmap(temp_f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
            for line in iter(mm.readline, b""):
                line = line.rstrip(b",\n")
                if line in [b"[", b"]"]:
                    continue
                yield json.loads(line)

补充说明

  • 为什么不能直接对bz2.open的文件对象做mmap?因为bz2.open返回的是流式文件对象,不支持随机访问(seek操作无效),而mmap要求文件对象必须可随机访问,且映射的是原始磁盘文件的字节,不是解压后的流数据。
  • 对于Wikidata这类超大dump文件,临时文件是最稳妥的方案——毕竟内存可能无法容纳整个解压后的文件。

内容的提问来源于stack exchange,提问作者sl_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:25:25