用 json.load() 读超大 JSON 文件必崩,应改用流式解析:对单数组用 JSONDecoder().raw_decode() 边读边解;NDJSON 用逐行 loads;深层嵌套或需路径提取时优选 ijson;注意 BOM、换行符及二进制打开模式。

用 json.load() 直接读超大 JSON 文件必崩
它会把整个文件一次性加载进内存解析成 Python 对象,哪怕只是 500MB 的 JSON 数组,也大概率触发 MemoryError。尤其当文件里是大量同构对象(比如日志、传感器记录、用户行为流)时,根本没必要全载入——你通常只关心逐条处理。
改用 json.JSONDecoder().raw_decode() 手动流式解析
这是标准库里最轻量的“边读边解”方案,不依赖第三方包,适合纯 JSON 数组或连续 JSON 对象流(如每行一个 JSON 对象)。关键在于跳过完整语法树构建,只按需提取顶层结构:
- 对单个巨型 JSON 数组:先定位到第一个
[,然后循环调用raw_decode(),每次取一个数组元素,直到遇到] - 对 NDJSON(每行一个 JSON):直接按行读取,每行用
json.loads(line.strip()),更简单且不易出错 - 注意
raw_decode()返回的是(obj, end_pos),必须用end_pos更新读取位置,否则会无限重复解析同一段
用 ijson 库做真正的迭代式解析(推荐)
当 JSON 结构嵌套深、字段多,或你只需要其中几个路径下的值(比如只取 data.items[].id 和 timestamp),ijson 是更稳的选择。它基于 C 扩展,内存占用恒定,支持 XPath 风格路径:
import ijson
with open('huge.json', 'rb') as f:
# 只提取所有 items 下的 id 字段,不构建整个 items 列表
ids = (item['id'] for item in ijson.parse(f, 'data.items.item'))
常见坑:ijson.parse() 返回的是事件流((prefix, event, value)),而 ijson.items() 更直观;务必用 rb 模式打开文件,否则在 Windows 上可能因换行符错位导致解析中断。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
立即学习“Python免费学习笔记(深入)”;
别忽略编码和 BOM 头问题
很多超大 JSON 文件由不同系统导出,开头带 UTF-8 BOM(\ufeff)或混用 \r\n,会导致 json 或 ijson 报 JSONDecodeError: Expecting value。解决方法很简单:
- 用
open(..., encoding='utf-8-sig')自动剥离 BOM - 若仍报错,先用
head -c 100 huge.json | hexdump -C查看前几字节是否含ef bb bf - NDJSON 场景下,用
line.strip()前先line.rstrip('\r\n'),避免 Windows 行尾干扰解析
真正卡住的往往不是解析逻辑,而是开头那几个不可见字符。

















