如何向.json文件的JSON数组追加数据而无需加载整个文件?
高效JSON数组文件追加写入解决方案
问题根因
你自定义的JsonWriter类问题在于没有区分首次写入和后续写入逻辑,第一次调用write_dict时会在左括号[后直接写入逗号,导致JSON语法错误。
修正后实现方案
下面的实现同时支持新建文件批量写入和已有JSON数组文件追加写入两种场景,全程无需加载整个文件内容,内存占用恒定,适合万级以上数据量的写入场景:
import json import os class JsonWriter: def __init__(self, filepath: str, overwrite: bool = False, indent: int = None): self.filepath = filepath self.indent = indent # 标记数组是否已有内容,判断是否需要加前置逗号 self._has_content = False # 文件已存在且不需要覆盖时,处理追加逻辑 if os.path.exists(filepath) and not overwrite: with open(filepath, 'rb+') as f: # 定位到文件末尾,跳过末尾空白字符找到闭合的] f.seek(-1, os.SEEK_END) while f.read(1).isspace(): f.seek(-2, os.SEEK_CUR) # 截断文件到]之前的位置 f.seek(f.tell() - 1) f.truncate() # 判断原数组是否为非空数组 self._has_content = os.path.getsize(filepath) > 1 else: # 新建文件写入数组开头标记 with open(filepath, 'w', encoding='utf-8') as f: f.write('[') def write_dict(self, dct: dict) -> None: jsn = json.dumps(dct, ensure_ascii=False, indent=self.indent) with open(self.filepath, 'a', encoding='utf-8') as f: if self._has_content: f.write(',\n') else: f.write('\n') self._has_content = True f.write(jsn) def close(self) -> None: # 补全数组闭合标记 with open(self.filepath, 'a', encoding='utf-8') as f: f.write('\n]') # 支持with上下文管理器,自动调用close避免格式错误 def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close()
使用示例
新建文件写入
# indent=4表示生成格式化的JSON,不需要可以去掉该参数 with JsonWriter('/home/test.json', overwrite=True, indent=4) as jw: jw.write_dict({"id": 1, "name": "测试1"}) jw.write_dict({"id": 2, "name": "测试2"}) jw.write_dict({"id": 3, "name": "测试3"})
追加到已有JSON文件
with JsonWriter('/home/test.json', indent=4) as jw: jw.write_dict({"id": 4, "name": "测试4"})
输出结果示例
生成的JSON完全符合语法规范:
[ { "id": 1, "name": "测试1" }, { "id": 2, "name": "测试2" }, { "id": 3, "name": "测试3" }, { "id": 4, "name": "测试4" } ]
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

