如何读取并提取AWS SageMaker生成的10GB拼接JSON文件条目
解决大体积拼接JSON文件的逐条目读取问题
你的核心问题是:文件是多个JSON对象直接拼接(无换行、无外层数组包裹),而for line in f会尝试将整个10GB文件一次性读入内存作为单行,直接触发内存溢出导致内核崩溃。
以下是三种可行的解决方案:
方案1:使用流式JSON解析库(推荐)
借助ijson库实现流式解析,无需加载整个文件到内存,每次仅处理单个JSON条目:
- 安装依赖:
pip install ijson
- 示例代码:
import ijson def process_entry(entry): # 替换为你的后处理逻辑 vectors = entry["vectors"] # 示例:统计当前条目的向量数量 print(f"当前条目包含 {len(vectors)} 个向量") with open("your_10gb_file.json", "rb") as f: # 逐解析每个独立的JSON对象 for entry in ijson.items(f, ""): process_entry(entry)
ijson会逐字节扫描文件,仅在内存中保留当前正在解析的条目,彻底避免内存过载问题。
方案2:手动按JSON边界分割解析
如果不想引入第三方库,可以通过跟踪大括号嵌套计数,手动分割并解析每个完整的JSON对象:
import json def process_entry(entry): # 替换为你的后处理逻辑 pass with open("your_10gb_file.json", "r") as f: buffer = [] brace_depth = 0 while True: char = f.read(1) if not char: # 处理文件末尾剩余的缓冲区内容 if buffer: entry = json.loads("".join(buffer)) process_entry(entry) break buffer.append(char) if char == "{": brace_depth += 1 elif char == "}": brace_depth -= 1 # 当大括号回到顶层时,说明一个完整JSON对象结束 if brace_depth == 0: entry = json.loads("".join(buffer)) process_entry(entry) buffer = []
方案3:预处理文件添加换行分隔
如果有足够临时磁盘空间,可以先给每个JSON对象末尾添加换行,之后即可用常规逐行读取方式处理:
# 第一步:格式化文件,给每个完整JSON对象添加换行 with open("large_raw.json", "r") as in_f, open("formatted_file.json", "w") as out_f: brace_depth = 0 while True: char = in_f.read(1) if not char: break out_f.write(char) if char == "}": brace_depth -= 1 if brace_depth == 0: out_f.write("\n") elif char == "{": brace_depth += 1 # 第二步:逐行读取格式化后的文件 with open("formatted_file.json", "r") as f: for line in f: entry = json.loads(line.strip()) process_entry(entry)
注意:此方案需要额外约10GB磁盘空间存储格式化后的文件。
内容的提问来源于stack exchange,提问作者sonny
相关产品推荐
相关产品推荐

