如何在Python中分块流式写入大量对象为JSON格式?
问题:大对象列表分块流式写入JSON格式
我现在需要处理大量数据,将对象列表写入JSON文件,但当前方法内存占用过高:
from pydantic import BaseModel import json class MyObj(BaseModel): # 字段定义 ... data = [] with open('file_to_process', 'rt') as fin: for x in fin: # 处理每行数据生成MyObj实例 ... data.append(MyObj(...)) with open('foo.json', 'w') as fout: json.dump([x.model_dump() for x in data], fout)
尝试用json-stream库实现流式写入,虽然降低了内存消耗,但它是逐个写入对象。我想实现分块流式写入——每生成1000个对象就写入一次,再继续处理下一批。
解决方案:手动分块控制流式写入JSON
不需要依赖额外库,直接手动控制JSON数组的结构,就能实现分批次写入,内存仅保留当前批次的对象,完全可控。具体实现如下:
from pydantic import BaseModel import json class MyObj(BaseModel): # 替换为你的字段定义 id: int content: str BATCH_SIZE = 1000 def process_and_write(): with open('file_to_process', 'rt') as fin, open('foo.json', 'w') as fout: # 先写入JSON数组的开头 fout.write('[') batch = [] first_batch = True for line_num, line in enumerate(fin, 1): # 处理每行数据,生成MyObj实例 # 示例处理逻辑,替换为你的实际代码 obj_data = {"id": line_num, "content": line.strip()} obj = MyObj(**obj_data) batch.append(obj.model_dump()) # 当批次达到指定大小,写入文件 if len(batch) >= BATCH_SIZE: if not first_batch: # 非第一个批次,先写逗号分隔 fout.write(',') # 将批次转为JSON字符串写入 json.dump(batch, fout, indent=2) # 清空批次,准备下一批 batch = [] first_batch = False # 处理剩余不足一个批次的对象 if batch: if not first_batch: fout.write(',') json.dump(batch, fout, indent=2) # 写入JSON数组的结尾 fout.write(']') if __name__ == "__main__": process_and_write()
核心逻辑说明:
- 手动维护JSON数组结构:先写
[,最后写],批次之间用逗号分隔,保证JSON格式合法 - 每收集
BATCH_SIZE个对象就写入一次,写完后清空批次列表,立即释放内存 - 单独处理最后一批不足
BATCH_SIZE的对象,避免遗漏数据 - 内存始终只保留当前批次的最多1000个对象,内存占用稳定可控
对比json-stream的优势:
- 自主控制写入时机和批次大小,减少频繁小IO带来的性能损耗
- 无需依赖第三方库,代码轻量且可定制性强
- 内存占用严格限制在批次范围内,适配超大规模数据场景
内容的提问来源于stack exchange,提问作者user4979733
相关产品推荐
相关产品推荐

