LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

JSONL:我们竟然忽略了这种格式的存在

admin
2026年9月18日 11:14 本文热度 47

JSON几乎无处不在。

只要需要序列化结构化数据,我们最先想到的通常就是JSON。API响应里有它,配置文件里有它,导出的业务数据离不开它,保存在本地的文件也经常使用它。

而且,JSON语法并不复杂。作为开发者,我们每天都在接触它,似乎早已摸清了它的全部用法。

真的如此吗?

前段时间,我听一档播客时,主持人无意中说了一句话,大意是:

“我们使用JSONL在本地保存记录。”

停顿了一下,他又特意补充:

“注意,是JSONL,不是JSON。”

显然,在他看来,这两个格式之间的区别非常重要。

其实,我大约一年前就听说过JSONL,只是当时没有深入了解,很快便把它忘在了脑后。再次听到这个名字时,我隐约觉得熟悉,却说不清它与普通JSON究竟有什么不同,更不知道开发者为什么需要关心它。

直到真正开始研究,我才意识到:我们口中的“JSON”,并不是一个孤立的格式。围绕JSON,早已形成了一整个衍生生态。过去这些年里,人们不断扩展或调整基础规范,用来解决原始JSON并未针对的问题。

例如,JSON5允许使用注释和尾随逗号,更适合由人手动编辑的配置文件;JSONC也就是“带注释的JSON”,被VS Code等工具广泛采用;BSON是Binary JSON,即二进制JSON,支撑着MongoDB的内部数据存储;EJSON代表Extended JSON,它补充了更多数据类型;GeoJSON则专门用于表示地理空间数据。

除此之外,大概还有十几种类似格式没有被列出来。

不过,这些衍生格式大多服务于特定领域。GeoJSON面向地图应用,BSON主要用于数据库内部,JSON5则适合需要注释和宽松语法的配置文件。它们解决的,都是具体场景下的具体问题。

JSONL有所不同。

JSONL的全称是“JSON Lines”,它解决的是适用范围更广的一类难题:流式处理与内存占用。

它允许程序逐行处理数据,不必先把整个文件加载进内存。如果数据量不断增长、通过数据流持续到达,或者文件大到足以耗尽可用内存,JSONL就能非常自然地应对。

它没有修改JSON对象本身的语法,只是改变了多个JSON对象在文件中的组织方式。

真正的区别,只有一行

从技术层面看,JSON与JSONL的差异并不复杂。

JSON只有一个根结构。

整个数据集必须是一个对象或一个数组。假设文件里存在一千条记录,那么,这一千条数据通常都会被包裹在同一个JSON数组中。

使用许多常见的立即加载型或缓冲型解析器时,程序需要先把完整内容读入内存,才能解析并使用这些数据。

JSONL则由多个相互独立的JSON对象组成,每行一个。

文件里的每一行,都是一条完整、有效且能够单独解析的JSON记录。一千条数据,就是一千行;各行彼此独立,不需要共享外层数组。

实际效果如下:

// 普通JSON:所有记录共同组成一个结构
{
  "records": [
    {"id": 1, "name": "Alice", "status": "active"},
    {"id": 2, "name": "Bob", "status": "inactive"},
    {"id": 3, "name": "Carol", "status": "active"}
  ]
}
// JSONL:每行都是一条独立记录
{"id": 1, "name": "Alice", "status": "active"}
{"id": 2, "name": "Bob", "status": "inactive"}
{"id": 3, "name": "Carol", "status": "active"}

看上去,不过是增加了几个换行符。

然而,正是这些换行符,彻底改变了程序处理数据的方式。

标准化,才是JSONL真正的优势

看到这里,有人可能会问:

“我们自己把JSON对象逐行写入文件,再编写一个按换行符拆分内容的解析器,不也能获得相同效果吗?”

从技术上来说,确实可以。

可是,JSONL真正重要的地方,不只是“每行放一个JSON对象”,而在于它已经是一种被广泛识别的标准格式

使用JSONL,意味着我们没有在项目中发明一套私有规则,而是在采用现有生态已经支持的解决方案。

Apache Spark和Hadoop可以直接高效处理JSONL文件;Python的pandas只需要调用一次函数,并设置read_json(lines=True),就能读取对应内容。

开发者不必重新编写解析器,也不用亲自处理流式读取、错误恢复和各种边界情况。那些经过大量真实项目验证的工具,已经替我们完成了这些工作。

如果坚持使用自定义格式,接下来需要维护的东西会越来越多:

  • 某一行数据格式错误时,程序应该跳过还是终止?
  • 错误应该如何向上层传递?
  • 文件末尾是否允许出现空行?
  • 团队采用了哪些特殊约定?
  • 为什么不直接使用现有标准?
  • 新加入的开发者该去哪里了解这些规则?

这些工作不会为业务创造更多价值,却会持续增加维护成本。

当另一名开发者看到扩展名为.jsonl的文件时,即使他暂时不了解全部细节,也很容易查到它的结构和处理方式。

格式本身就在传递信息。

相反,如果文件采用的是团队自创格式——哪怕规则只是“使用换行符分隔JSON对象”——也会产生额外的文档负担和理解成本。

标准化带来的价值还不止于文件读取。

许多数据库导入工具都能识别JSONL;ETL工具通常提供原生的JSONL读取器;jq等命令行工具只需极少配置,就可以处理JSONL数据流。

选择成熟标准,而不是重复造轮子,这些能力几乎都可以直接获得。

JSONL为什么重要:内存与流式处理

使用普通JSON文件和缓冲型解析器时,程序一般需要经历以下过程:

先读取整个文件,再解析完整结构,接着在内存中建立全部对象树,最后才能真正处理数据。

JSONL的流程却完全不同:

读取一行,解析这一行,处理这一条记录,然后继续读取下一行。

循环往复,直到文件结束。

假设有一个50MB的普通JSON文件。使用缓冲型解析器时,程序至少需要为原始数据准备约50MB内存;由于解析后还要构建对象结构,实际占用通常会更高。

如果同样的数据以JSONL保存,程序只需要容纳当前正在处理的一行。换句话说,内存需求主要取决于最大单条记录的大小,而不是整个文件的体积。

通常情况下,一条记录显然要比完整文件小得多。

当然,JSON并非完全无法进行流式解析。

例如,Python生态中有ijson,Node.js中也有stream-json。这些工具能够逐步解析复杂、嵌套的JSON结构,包括层级很深的对象和数组,而不必把整份文档一次性加载到内存。

不过,流式JSON解析器与JSONL解决的是两类相互补充的问题。

流式解析器能够保留复杂的数据层次,同时增量读取内容;JSONL则要求把数据整理为“一行一条记录”的形式,用结构上的简化换取处理方式上的简单。

换句话说:

  • 流式JSON解析适合必须保留复杂嵌套结构的数据;
  • JSONL适合彼此独立、能够按行拆分的扁平记录。

JSONL的一项明显优势在于,它只依赖任何编程语言都具备的基础文件操作。

程序只需要逐行读取,再把当前行交给普通JSON解析器即可。无需引入专门的流式解析库,也不用实现复杂的状态管理。

另一个好处,是程序可以在数据到达时立即开始处理。

如果我们正在持续读取日志文件,或者消费一个已经采用JSONL格式的数据流,那么,每收到一条记录,就能立刻解析和执行相应逻辑。

程序不必等待数据流彻底结束,更不需要苦等最后那个JSON数组闭合符号出现。

播客中的主持人,正是使用JSONL在本地保存应用日志。

仔细想想,这个选择再合理不过:日志只会不断追加,文件体积可能极其庞大,而且经常需要增量处理。

JSONL天然适合这种场景。

JSONL最适合用在哪里

JSON依然有大量合理用途。不过,在下面这些场景中,确实值得优先考虑JSONL。

日志文件与事件流

日志中的每条记录通常相互独立,因此非常适合使用JSONL。

Apache访问日志、应用遥测数据、错误追踪记录,以及其他会随时间持续积累的数据,都可以逐条写入文件,再按需读取,无须一次加载全部内容。

Elasticsearch、Logstash等工具也能通过标准配置接收JSONL数据。

对于日志系统而言,JSONL还有一个非常实际的优势:追加新记录十分简单。

只需要在文件末尾写入新的一行,不必读取并修改整个数组,也不用担心重新生成庞大的根结构。

机器学习流水线

机器学习训练数据往往规模巨大,不适合一次性放入内存。

采用JSONL后,训练程序可以逐条或分批读取数据,再将当前批次送入训练循环。处理完成后释放相关内存,然后继续加载下一批。

Hugging Face的datasets库除了支持Arrow、Parquet和CSV等主要格式,也支持JSONL。

原因并不神秘:逐行记录让增量读取变得非常直接。

当数据集包含数百万甚至数千万条样本时,这种简单结构会带来实实在在的便利。

消息队列

Kafka等消息队列也适合处理类似JSONL的独立消息负载。

每条消息都是完整记录,消费者可以分别解析和处理,不需要共同维护一个庞大的数据结构。

由于消息之间没有外层数组依赖,系统也更容易进行并行消费,把不同记录分配给多个消费者处理。

简单的格式,反而让工作拆分与分发更加容易。

大数据处理

Apache Spark和Hadoop等大数据框架能够很好地处理JSONL。

框架可以把文件分配给不同节点,再并行处理各个部分。

从理论上讲,JSON数组和JSONL文件都能按照字节偏移进行拆分。然而,如果直接切割JSON数组,系统必须追踪方括号、对象边界以及嵌套关系,才能保证切割后的内容仍然有效。

JSONL就简单得多。

只要找到换行符,便能较为安全地确定记录边界。即使采用最朴素的按行拆分策略,通常也能正确分配数据。

这正是JSONL在分布式处理中的优势:它不是提供了JSON无法实现的能力,而是让原本复杂的操作变得更容易、更可靠。

ETL数据流水线

ETL指的是数据的提取、转换和加载。

当数据需要在多个系统之间流动时,JSONL的标准化结构同样能够发挥作用。

程序可以轻松追加新记录,也能只处理文件中的某个部分,不必先构造完整数据集。与此同时,多数ETL工具都能识别这种格式,并提供经过优化的读取器。

团队不需要维护额外适配代码,也不必为每个系统设计不同的数据交换规则。

流式API

越来越多的API开始采用增量方式向客户端发送结果。

以OpenAI的流式API为例,它使用Server-Sent Events,也就是SSE格式。每个事件中可以包含一个JSON对象,客户端收到数据后便能立即处理,而不必等待完整响应全部生成。

严格来说,SSE并不等同于JSONL,但两者背后的思路非常接近:

把完整结果拆成可以独立处理的小记录,并在它们到达时立即消费。

因此,只要面对的是持续到达的大量数据,或者需要增量处理的内容,JSONL往往都能体现优势。

更重要的是,相关生态已经存在,我们不必从零开始搭建所有工具。

哪些情况继续使用JSON更合适

JSONL并不是JSON的替代品。

在很多场景中,传统JSON仍然是更自然、更简单的选择。

REST API与浏览器应用

REST API和浏览器应用已经围绕JSON形成了非常成熟的生态惯例。

几乎所有HTTP客户端与服务端框架都内置了JSON支持。传统REST接口通常返回JSON数组,或者返回包含分页信息的JSON对象。

JavaScript本身还提供了JSON.parse()JSON.stringify(),处理起来十分直接。

JSONL当然也能用于这些场景,但需要增加一层逐行拆分和解析逻辑。虽然实现并不困难,却没有必要为了使用新格式而对抗成熟惯例。

如果现有方式已经简单、可靠,就没有必要强行改变。

配置文件

配置文件通常体积较小,而且程序启动时往往需要一次性读取全部内容。

与此同时,配置项天然具有层级关系。例如,数据库配置下面可能包含地址、端口、用户名和连接池参数;日志配置又会包含级别、输出位置以及格式选项。

JSON的嵌套结构非常适合描述这种层级信息。

我们原本就希望把整份配置加载进内存,因此,JSON的单一根结构反而更加自然。

文档数据库

MongoDB等文档数据库采用JSON风格的数据结构,目的就是支持内容丰富、层次复杂的文档。

一个文档内部可以包含对象、数组以及多层嵌套关系,从而表达复杂的数据联系。

在这种情况下,结构本身就是重点。将文档强行拆成一行一条的扁平记录,反而可能破坏其原有表达能力。

中小规模数据集

如果整个数据集只有几MB,而且程序本来就准备一次性加载全部内容,那么,JSONL带来的内存优势不会特别明显。

此时,JSON的单一结构更容易读取、修改和传递。

为了标准化而增加的逐行处理逻辑,也未必能换来足够收益。

因此,选择JSON还是JSONL,最终可以归结为一个简单判断:

如果数据规模有明确上限,能够轻松放入内存,而且需要作为一个整体处理,就使用JSON。

如果数据没有固定上限,体积非常庞大,或者希望逐条增量处理,就应该考虑JSONL。

关键不在于哪个格式更新,而在于数据将以什么方式产生、增长和被消费。

那么,NDJSON又是什么

熟悉JSON各种衍生格式的人,可能还会提到NDJSON

NDJSON的全称是Newline-Delimited JSON,也就是“以换行符分隔的JSON”。

它与JSONL一样,规定文件中的每一行都应该是一条完整的JSON对象。

那么,两者究竟有什么区别?

在大多数实际场景中,区别主要体现在文件扩展名和命名习惯上。

文件名以.jsonl结尾,通常就称为JSONL;如果后缀写成.ndjson,人们便会称它为NDJSON。

除此之外,两者表达的核心思想基本相同:每行一条独立JSON记录。

因此,不必在名称上纠结太久。真正重要的是团队保持一致,并让使用的工具能够正确识别对应格式。

为什么JSONL很少被重点讨论

我一直不太确定,为什么人们很少专门谈论JSONL。

也许关于它的讨论其实一直存在,只是我恰好错过了。又或许,真正的原因更加简单:JSONL实在太朴素了。

它没有需要花几周学习的新框架,没有等待加入的庞大社区,也很少有人在技术大会上把它包装成“革命性的下一代方案”。

它只是一种格式。

一行,一个JSON对象。

没了。

可恰恰是这种不引人注目的工具,往往最实用。它安静地完成任务,现有生态也已经提供了完善支持,开发者根本不用反复思考底层细节。


阅读原文:点击这里


该文章在 2026/9/18 11:16:58 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-1  粤公网安备44030602007207号