什么是 JSONL?JSON Lines 格式完全指南
关于 JSON Lines 你需要知道的一切——语法、示例、使用场景和最佳实践。
最后更新:2026年2月
什么是 JSONL?
JSONL(JSON Lines),也称为 Newline Delimited JSON (NDJSON),是一种基于文本的数据格式,其中每一行是一个有效的 JSON 值,用换行符分隔。与将数据包装在单个数组或对象中的标准 JSON 不同,JSONL 每行存储一条记录。
这种简单的设计使 JSONL 非常适合流式处理、日志记录和处理大型数据集——每行都可以独立读取、解析和处理,无需将整个文件加载到内存中。
该格式由处理大量数据的工具和平台推广使用,包括 OpenAI(用于微调数据集)、BigQuery、Apache Spark 和日志管理系统。
JSONL 语法规则
JSONL 格式遵循几个简单的规则:
- 每行必须是一个有效的 JSON 值(对象、数组、字符串、数字、布尔值或 null)
- 行之间用换行符(\n)分隔
- 行之间没有逗号或分隔符
- 文件必须使用 UTF-8 编码
- 文件末尾的换行符是可选的
- 大多数解析器会忽略空行
{"name":"Alice","age":30,"city":"New York"}
{"name":"Bob","age":25,"city":"London"}
{"name":"Charlie","age":35,"city":"Tokyo"}注意:每行都是一个完整的、独立的 JSON 对象。行之间没有逗号,也没有外层数组包裹。
JSONL 示例
{"id":1,"name":"Alice","email":"alice@example.com"}
{"id":2,"name":"Bob","email":"bob@example.com"}
{"id":3,"name":"Charlie","email":"charlie@example.com"}{"user":{"name":"Alice","age":30},"scores":[95,87,92]}
{"user":{"name":"Bob","age":25},"scores":[88,91,76]}JSONL 的每一行不需要是相同类型——只要每行是有效的 JSON 即可:
{"event":"login","user":"alice","timestamp":"2026-01-15T10:30:00Z"}
{"event":"purchase","user":"alice","amount":29.99,"items":["book","pen"]}
{"event":"logout","user":"alice","timestamp":"2026-01-15T11:45:00Z"}JSONL 最流行的用途之一是 OpenAI 微调数据集:
{"messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"What is JSONL?"},{"role":"assistant","content":"JSONL is a text format where each line is a valid JSON value."}]}
{"messages":[{"role":"system","content":"You are a helpful assistant."},{"role":"user","content":"How do I read a JSONL file?"},{"role":"assistant","content":"Read the file line by line, parsing each line as JSON."}]}如何读取 JSONL 文件
JSONL 文件可以用任何支持逐行文本处理的工具读取。以下是最常用的方法:
使用标准 Unix 工具检查 JSONL 文件:
# 查看前 5 行
head -n 5 data.jsonl
# 统计总行数(记录数)
wc -l data.jsonl
# 用 jq 美化打印每一行
cat data.jsonl | jq .
# 按字段值筛选
cat data.jsonl | jq 'select(.age > 30)'Python 内置的 json 模块天然支持 JSONL 处理:
import json
with open('data.jsonl', 'r') as f:
for line in f:
record = json.loads(line)
print(record['name'])在 Node.js 中逐行读取 JSONL 文件:
import { createReadStream } from 'fs';
import { createInterface } from 'readline';
const rl = createInterface({
input: createReadStream('data.jsonl')
});
for await (const line of rl) {
const record = JSON.parse(line);
console.log(record.name);
}如何创建 JSONL 文件
创建 JSONL 文件非常简单——只需每行写入一个 JSON 值。
import json
records = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35},
]
with open('output.jsonl', 'w') as f:
for record in records:
f.write(json.dumps(record) + '\n')import { writeFileSync } from 'fs';
const records = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 35 },
];
const jsonl = records
.map(r => JSON.stringify(r))
.join('\n');
writeFileSync('output.jsonl', jsonl + '\n');JSONL 中可以添加注释吗?
不可以。JSONL 规范不支持注释。JSONL 文件中的每一行都必须是有效的 JSON 值——而 JSON 本身没有注释语法。
如果你需要在数据旁边包含元数据或注解,常见的变通方法包括:
- 1在 JSON 对象中添加元数据字段:{"_comment": "测试数据", "name": "Alice"}
- 2使用单独的元数据文件与 JSONL 文件配合
- 3将元数据作为文件的第一行:{"_meta": {"version": "1.0", "created": "2026-01-15"}}
请注意,任何「注释」字段都会被作为常规数据解析。消费 JSONL 文件的应用程序应该设计为忽略元数据字段。
JSONL 与 JSON 对比
关键区别在于结构。JSON 将所有内容包装在单个值中,而 JSONL 每行存储一个值。
[
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
]{"name":"Alice","age":30}
{"name":"Bob","age":25}- JSON 必须完全加载到内存中才能解析;JSONL 可以逐行读取
- JSON 元素之间需要逗号;JSONL 使用换行符
- JSON 更适合配置文件和 API;JSONL 更适合大型数据集和流式处理
- 向 JSON 追加数据需要重写整个文件;JSONL 只需追加新行
查看完整对比,请参阅我们的 JSON vs JSONL guide.
常见使用场景
机器学习与人工智能
最流行JSONL 是 ML 训练数据的标准格式。OpenAI、Hugging Face 和其他 AI 平台使用 JSONL 格式的微调数据集,因为每个训练样本都是一个独立的行,可以高效地进行随机打乱、采样和流式处理。
日志文件与事件流
JSONL结构化日志系统(ELK 堆栈、Datadog、CloudWatch)以 JSONL 格式输出日志。每条日志记录为一行 JSON,便于追加新条目和实时处理日志。
大数据处理
JSONLApache Spark、BigQuery 和 AWS Athena 等工具原生支持 JSONL。逐行格式允许跨分布式系统并行处理——每个工作节点可以独立处理一部分行。
流式 API
JSONL返回大型结果集的 API 通常使用 JSONL 流式传输。客户端可以在结果到达时立即开始处理,无需等待完整响应。
JSONL 文件扩展名
JSONL 文件通常使用以下扩展名:
这三种扩展名包含相同的格式——每行一个 JSON 值。JSONL 的 MIME 类型为 application/jsonl 或 application/x-ndjson。