精通 JSONL 文件:结构、使用场景与核心优势

一个 JSONL 文件每行包含一个完整的 JSON 值。官方文档将其称为“JSON Lines 文本格式,也称为换行符分隔的 JSON”。正是这一条规则,使其能够很好地进行流式传输、在部分读取时得以幸存,以及为什么电子表格无法打开它。
什么是 JSONL 文件?
JSON Lines 是一种用于记录的文本格式。规范将其描述为“一种用于存储结构化数据的便捷格式,可以一次处理一条记录”。
文档明确指出了它的适用场景。它“能很好地与类 Unix 风格的文本处理工具和 Shell 管道协同工作”,页面还补充道“它是日志文件的绝佳格式”。它也被描述为“一种在协作进程之间传递消息的灵活格式”。
与普通 JSON 的对比才是重点。一个包含 100 万条记录的 JSON 数组是一个值:读取器必须消耗整个数组才能完成结构解析。而一个包含 100 万条记录的 JSONL 文件则是 100 万个值,并且每一行都是独立的。
还有第二个密切相关的规范。NDJSON 规范对此非常直接:“目前还没有在流协议中传输 JSON 文本实例的标准。”它声明的使用场景是“通过 TCP 或 UNIX 管道等流式传输协议交付多个 JSON 文本实例”。
JSONL 文件的结构
三个要求
JSON Lines 文档恰好列出了三个。第一个是UTF-8 编码。它带有一个借鉴自 JSON 本身的警告:“与 JSON 标准一样,绝不能包含字节顺序标记 (U+FEFF)。”
第二个是每一行都是一个有效的 JSON 值。页面指出“最常见的值将是对象或数组,但允许使用任何 JSON 值。”然后它给出了一个让人困惑的边缘情况:“null 是一个有效值,但空行不是。”
第三个是行终止符是 \n。Windows 的换行符仍然有效。给出的原因是机械性的:“这意味着 \r\n 也是支持的,因为在解析 JSON 值时,周围的空白字符会被隐式忽略。”
行内绝不能出现的内容
正是这个约束使得该格式得以运行。NDJSON 规范将其列为一项要求:“JSON 文本绝不能包含换行符或回车符。”
JSON 值通常允许通过缩进跨越多行。但在行分隔文件中则不行,因为换行符是记录分隔符。每条记录都必须写在物理上的一行中。
尾行与空行
这两个规范之间有两个细节不同,当文件被拒绝时,这两个细节都很重要。
以尾随换行符为例。JSON Lines 表示“强烈建议但在文件中最后一个 JSON 值之后包含行终止符并不是必需的。”
在空行上,这两个规范存在分歧。JSON Lines 非常严格:空行不是有效值。NDJSON 则比较宽容,允许“解析器可以默默忽略空行”,同时要求“必须对这种行为进行记录”。
扩展名和媒体类型
命名也有所不同。JSON Lines 表示文件“可以使用文件扩展名 .jsonl 保存”。在媒体类型方面,它表示“MIME 类型可以是 application/jsonl,但这尚未标准化”。NDJSON 表示媒体类型“应该为 application/x-ndjson”,扩展名“应该为 .ndjson”。
对于压缩,JSON Lines 推荐使用流式压缩器:“推荐使用 gzip 或 bzip2 来节省空间,从而生成 .jsonl.gz 或 .jsonl.bz2 文件。”
在阅读错误消息时,有一个小惯例值得了解。文本编辑器将第一行称为“第 1 行”。文档对此进行了延伸:“JSON Lines 文件中的第一个值也应该被称为‘值 1’。”
JSONL 的用途
您通常会在以下四种情况之一中遇到 .jsonl 文件。
日志和事件文件。 该格式自身的文档指出了日志文件,原因在于写入器可以一次追加一行,而无需重写任何内容。
数据仓库加载。 Google 的 BigQuery 文档是该格式官方地位的一个很好例子。它支持从 Cloud Storage 加载“换行符分隔的 JSON (ndJSON) 数据”,并且其文件格式选择器将该选项列为“JSONL (换行符分隔的 JSON)”。
嵌套记录的 API 导出。 无法干净地扁平化为列的数据会保留其每行的嵌套。包含可变数量商品的订单行就是经典案例。
机器学习数据集。 训练集和评估集通常以这种方式分发,因为训练循环会一次读取一条记录。
共同的主线是流式传输。当文件是增量生成或增量消耗时,它就成为了显而易见的选择。
JSONL 对比 JSON 对比 CSV
| JSONL | JSON | CSV | |
|---|---|---|---|
| 文件单位 | 每行一个值 | 整个文件一个值 | 每行一行 |
| 嵌套数据 | 是,每条记录 | 是 | 原生不支持 |
| 追加记录 | 添加一行 | 重写容器 | 添加一行 |
| 部分读取有用 | 是 | 极少 | 是 |
| 在电子表格中打开 | 否 | 否 | 通常可以 |
| 记录结构可以不同 | 是 | 是 | 否,列是固定的 |
| 在编辑器中人类可读 | 是,每条一条长行 | 是,缩进时 | 是 |
最让人感到意外的是倒数第二行。同一个 JSONL 文件中的两行可以携带不同的键。这正是该格式灵活的原因,也正是为什么简单的导入会导致列参差不齐。
对于面向列的二进制替代方案,Parquet 解析从存储的角度涵盖了相同的领域。对于最简单的表格情况,TSV 详解涵盖了制表符分隔的文本。
主要优势
仅追加写入。 新记录就是新的一行。文件中先前的内容无需更改。
流式读取。 消费者可以在第 200 万条记录被写入之前处理第一条记录。
容错性。 即使文件被截断,直到最后一个完整行之前的内容仍然是可读的。而截断的 JSON 数组通常完全无法读取。
保留嵌套。 CSV 必须扁平化的结构在每条记录内部保持完好。
对 Shell 友好。 文档将其归功于类 Unix 风格的文本处理和 Shell 管道,因为面向行的文件可以与面向行的工具协同工作。
数据仓库支持。 BigQuery 的文档声明了它强制执行的规则:“文件中的每个 JSON 对象必须位于单独的行中。”
JSONL 不再起作用的地方
该格式解决了传输和追加问题。但它无法解决您对内容的任何疑问。
压缩是一项真正的权衡,而不是免费的午餐。BigQuery 的文档直言不讳地指出了其代价:“如果您使用 gzip 压缩,BigQuery 将无法并行读取数据。”它还补充道,“将压缩的 JSON 数据加载到 BigQuery 中比加载未压缩的数据要慢。”该格式自己的页面推荐使用 gzip 来节省空间。这两者都是事实,但它们的发展方向相反。
它也很冗长。每一行都会重复每个键名,因此宽记录集会比列式格式的相同数据大得多。
而且它对一致性只字未提。允许具有不同结构的记录,这意味着一个字段可以在文件进行到一半时悄然停止出现,而不会导致任何内容失效。
如果您不是工程师,如何处理 JSONL 文件
这就是实际的差距。业务工具期望行和列,而 .jsonl 文件无法像 CSV 那样打开。
务实的途径是进行转换步骤。向生成该文件的人索取您所需字段的扁平化 CSV 或 Excel 提取物。或者您自己使用任何支持 JSON 的工具将其扁平化。您会失去嵌套,但一旦您决定了分析要使用哪些字段,这通常就无所谓了。
从那时起,工作就是普通的分析。Powerdrill Bloom 的定价页面列出了 Excel、CSV、PDF 和文档的上传选项,因此扁平化的提取物可以直接导入。问题是用自然语言提出的,而不是写成查询。CSV AI assistant 涵盖了这一路径,而 data connectors 则涵盖了更适合从源头拉取数据而不是导出的情况。
值得记住的区别是,这是在您上游做出的传输决策。一旦文件到达您的办公桌,将其转换掉是正常的,而不是一种权宜之计。
结论
JSONL 是一种只有一条规则的文本格式:每行一个完整的 JSON 值,且值内部没有换行符。这条规则带来了可追加性、流式传输和部分读取容错性,这就是为什么日志和仓库加载默认使用它的原因。
它无法带来的是表格。当文件到达需要答案而不是管道的人手中时,有用的下一步就是扁平化的提取物和提问。
如果您正处于这种境地,请使用转换后的文件尝试 Powerdrill Bloom,并从将其转换为图表开始。
常见问题
JSONL 文件有什么用途?
它用于记录流:日志文件、事件导出、仓库加载和机器学习数据集。该格式的文档特别指出了日志文件和 Shell 管道。共同点是记录是一次写入或读取一条。
JSONL 和 NDJSON 有什么区别?
它们用不同的文书工作描述了同一个想法。JSON Lines 使用 .jsonl 扩展名,并指出 application/jsonl 尚未标准化。NDJSON 指定了 .ndjson 和 application/x-ndjson,并且它允许解析器忽略空行。
我可以在 Excel 中打开 JSONL 文件吗?
双击是无法打开的,因为每一行都是一个 JSON 值,而不是一行单元格。通常的方法是先将所需的字段扁平化为 CSV 或 Excel,或者使用直接读取该格式的工具。
为什么在 JSONL 中一条记录不能跨越多行?
因为换行符是记录分隔符。NDJSON 规范指出“JSON 文本绝不能包含换行符或回车符”。因此,美化输出的 JSON 必须折叠到每条记录一行。
JSONL 文件中允许有空行吗?
这两个规范有所不同。JSON Lines 指出“null 是一个有效值,但空行不是”。NDJSON 允许解析器默默忽略空行,前提是该行为已被记录。