← 中文资源

简体中文版本

逐行读取 JSONL 记录

使用生成器逐行解析 JSONL 文件,跳过空行,对超长记录和非法 JSON 抛出带行号的错误,避免一次性载入整个文件。

阅读英文原文

功能说明

read_jsonl 是一个生成器,按行读取 JSON Lines 文件,每次只把一个对象放进内存。空行会被跳过;单行字节数超过上限、JSON 语法错误或顶层不是对象时,都会抛出带行号的 JsonlError,便于定位坏数据。示例先写入四条记录,其中第三条故意缺少值,演示读取在第 3 行停止。

关键代码

for line_no, raw in enumerate(handle, start=1):
    size = len(raw.encode("utf-8"))
    if size > max_record_bytes:
        raise JsonlError(line_no, f"record is {size} bytes, limit is {max_record_bytes}")
    line = raw.strip()
    if not line:
        continue
    record = json.loads(line)
    ...
    yield record

raw.strip() 只影响判断与解析,行号来自 enumerate,两者不会互相干扰。

使用注意

  • 大小限制按 UTF-8 字节数计算,而不是字符数,能真实反映内存占用。
  • 生成器保持文件打开,调用方应尽快消费完或显式关闭;提前 break 时由垃圾回收关闭文件。
  • 只接受 JSON 对象,数组或标量会报错;如果数据允许其他顶层类型,需要放宽检查。
  • 错误会立即终止迭代,已经产出的记录仍然有效;需要跳过坏行时可改成收集错误后继续。
  • 该函数不做编码探测,文件必须是 UTF-8;其他编码应在打开前转换。

验证方式

运行脚本会先打印 1、2 两条记录,然后输出 stopped after 2 records: line 3: invalid JSON。把第三条改成合法对象可读到第 4 条;把 max_record_bytes 调小可验证超长记录分支。