合并JSON文件时遭遇JSONDecodeError等异常的技术求助
解决多个JSON文件合并时的JSONDecodeError问题
听起来你遇到的问题很典型——当你用常规的json.load()去读取那些内容是字符串列表/多行独立JSON对象的文件时,就会触发JSONDecodeError,因为标准的json.load()要求整个文件是一个合法的单一JSON结构(比如一个数组或者一个对象),而不是多个零散的JSON字符串堆在一起。
我给你两种针对性的解决方案,你可以根据自己的文件格式来选:
方案一:处理每行一个JSON对象的文件(最常见情况)
如果你的每个JSON文件里是每行一个独立的JSON对象(比如每行是{"id": 1, "content": "xxx"}这种),那我们可以逐行读取并解析,再把所有对象合并到一个数组里:
import json import os def merge_json_files(input_dir, output_file): merged_data = [] # 遍历目标目录下的所有JSON文件 for filename in os.listdir(input_dir): if not filename.endswith('.json'): continue file_path = os.path.join(input_dir, filename) with open(file_path, 'r', encoding='utf-8') as f: # 逐行处理,跳过空行 for line in f: stripped_line = line.strip() if not stripped_line: continue try: # 解析单行JSON字符串 json_obj = json.loads(stripped_line) merged_data.append(json_obj) except json.JSONDecodeError as e: print(f"警告:解析文件 {filename} 的行时出错: {e}") # 将合并后的数组写入输出文件 with open(output_file, 'w', encoding='utf-8') as f: json.dump(merged_data, f, indent=2, ensure_ascii=False) # 使用示例:把./json_files目录下的所有JSON合并到merged.json merge_json_files('./json_files', 'merged.json')
这个方法的好处是轻量,不需要额外安装依赖,适合中小规模的文件。
方案二:处理包含连续JSON对象的大文件
如果你的JSON文件是多个JSON对象直接拼接在一起(比如{"a":1}{"b":2}这种没有换行也没有数组包裹的情况),或者文件特别大,一次性加载会占内存,那可以用ijson这个流式解析库来处理:
首先安装依赖:
pip install ijson
然后用下面的代码:
import json import ijson import os def merge_json_files(input_dir, output_file): merged_data = [] for filename in os.listdir(input_dir): if not filename.endswith('.json'): continue file_path = os.path.join(input_dir, filename) # ijson需要以二进制模式打开文件 with open(file_path, 'rb') as f: # 流式解析文件中的每个JSON对象 for json_obj in ijson.items(f, ''): merged_data.append(json_obj) with open(output_file, 'w', encoding='utf-8') as f: json.dump(merged_data, f, indent=2, ensure_ascii=False) # 使用示例 merge_json_files('./large_json_files', 'merged_large.json')
这个方法会逐段解析文件,不会把整个文件加载到内存里,适合处理几个GB级别的大JSON文件。
关键原理总结
你的错误根源在于:标准的json.load()会把整个文件内容当作一个完整的JSON结构来解析,但你的文件里是多个独立的JSON单元(不管是每行一个还是连续拼接),所以触发了"Extra data"错误。上面两种方法都是把这些独立的JSON单元逐个解析,再统一合并成一个合法的JSON数组写入大文件。
内容的提问来源于stack exchange,提问作者user9399405




