Python无法正确加载2-5GB JSON文件,寻求技术解决方案
分析与解决方案:大JSON文件加载报错问题
我来帮你拆解下这个棘手的问题——大JSON文件加载+格式错误的双重麻烦确实容易让人头大,咱们一步步来理清楚:
一、两种加载方法报错的核心原因
1. 整体加载报错(json.load)
你遇到的JSONDecodeError: Unterminated string有两个大概率原因:
- 文件真的被截断了:Glogg只能打开到第60608660行,说明文件在这个位置之后的数据可能丢失了,导致字符串没有闭合;
- 编码不匹配:Glogg显示格式为US-ASCII,但如果文件中包含非ASCII字符(哪怕是隐藏的),用默认编码打开会导致解析混乱,误以为字符串未终止。
2. 逐行加载报错
这个报错Expecting value: line 2 column 1完全是因为JSON语法错误!看你给出的文件结构:
[ { "column 1" : 1, ... } { "column 1" : 2, ... } ... ]
数组里的对象之间缺少逗号!正常JSON要求数组元素必须用逗号分隔,所以第二行的{会被解析器当成无效的起始字符,直接报错。这和逐行加载的逻辑无关,是文件本身的语法问题。
二、分步解决建议
第一步:修复JSON语法错误
先补上对象之间的逗号,这是最基础的前提。因为文件很大,不能一次性读入内存,推荐用逐行处理的脚本修复:
import os input_file = "Table.json" output_file = "Fixed_Table.json" with open(input_file, "r", encoding="utf-8") as in_f, open(output_file, "w", encoding="utf-8") as out_f: # 写入开头的[] first_line = in_f.readline() out_f.write(first_line) prev_line = None for line in in_f: stripped_line = line.strip() # 处理结尾的] if stripped_line == "]": # 检查上一行是否多写了逗号 if prev_line and prev_line.strip().endswith(","): out_f.write(prev_line.rstrip(",") + "\n") out_f.write(line) break # 给对象行补逗号 if stripped_line.startswith("{") and prev_line: if prev_line.strip().endswith("}"): out_f.write(prev_line.rstrip("\n") + ",\n") else: out_f.write(prev_line) prev_line = line # 处理未到结尾的情况 if prev_line and prev_line.strip() != "]": out_f.write(prev_line)
第二步:用流式解析处理大文件
哪怕修复了语法,直接用json.load加载2-5GB的文件还是会占用大量内存(哪怕你有32GB),推荐用专门的流式解析库ijson,它可以逐段读取JSON,内存占用极低:
- 先安装库:
pip install ijson
- 流式解析代码:
import ijson with open("Fixed_Table.json", "r", encoding="utf-8") as f: # 逐个解析数组里的对象 for item in ijson.items(f, "item"): # 这里可以处理单个对象,比如提取字段、存入数据库等 print(f"处理第{item['column 1']}条数据")
第三步:验证文件完整性与编码
- 检查文件是否截断:用命令行工具查看文件末尾(Linux/macOS用
tail -20 Table.json,Windows用type Table.json | tail -20),确认最后一行是],如果不是,说明文件确实不完整,需要重新获取完整文件; - 检测文件编码:用Python的
chardet库确认文件真实编码,避免编码不匹配导致的解析错误:
import chardet with open("Table.json", "rb") as f: encoding_result = chardet.detect(f.read(10000)) print(f"文件编码:{encoding_result['encoding']}")
之后打开文件时指定对应编码(比如encoding='gbk'或encoding='utf-8')即可。
总结
你的问题是JSON语法错误+可能的文件截断/编码不匹配共同导致的:先修复对象间的逗号,再用流式解析处理大文件,最后验证文件完整性和编码,就能解决问题了。
内容的提问来源于stack exchange,提问作者mimibao1009
相关产品推荐
相关产品推荐

