JSON衍生:JSON5、JSONL、JSONC、NDJSON、BSON、JSONB、JSONP、HOCON
概述
在逛GitHub看源码时,经常看到.jsonl
文件,也在JSON文件里看到常规JSON文件不能出现的注释,于是记录此文。
JSON5
官网,规范,GitHub。JSON的扩展,旨在使人类更易于手动编写和维护。是JSON的一个超集(superset),意味着所有合法的JSON都是合法的JSON5,但反之则不然。
通过直接从ECMAScript 5(简称ES5)添加一些最小的语法功能来实现。JSON5仍然是JS的严格子集,不添加任何新的数据类型,并且可以处理所有现有的JSON内容。
对比JSON格式
key
只要是有效标识符,可不加引号,即使是ES5中的保留关键字key-value
都可使用单引号- 对象和数组尾巴都可跟着逗号
- 字符串可以是多行的,只要加上反斜杠
- 数字可以是十六进制(基数为16)/以小数点开头或结尾/包括Infinity,-Infinity,NaN和-NaN/以明确的加号开始。
- 允许使用注释,单行(
//
)、多行(/* */
)都可以
示例:
{// commentsunquoted: 'and you can quote me on that',singleQuotes: 'I can use "double quotes" here',lineBreaks: "Look, Mom! \No \\n's!",hexadecimal: 0xdecaf,leadingDecimalPoint: .8675309, andTrailing: 8675309.,positiveSign: +1,trailingComma: 'in objects', andIn: ['arrays',],"backwardsCompatible": "with JSON",
}
npm install json5
pip install json5json5.loads(json5_string)
# data是Python字典
json5_string = json5.dumps(data, indent=4)
JSONL
即JSON Lines缩写,官网,将每个JSON对象(数组,下同,不再赘述;对象更常见)放在文件的单独一行中,使用换行符(\n
)作为对象之间的分隔符。文件后缀名为.jsonl
。
JSONL文件:
- 逐行处理:每一行是一个独立的有效JSON对象,可单独解析;
- 无分隔符:相较于传统的JSON数组格式,JSONL不使用逗号或其他分隔符来分隔对象;
- 简洁高效:处理大型数据集时更加高效,可有效避免内存溢出问题,且更易于读写;
- 适用场景:适合日志、传感器数据、流式处理、以及需要将每条记录单独存储或传输的场景。
JSON对比JSONL
- JSON:通常是一个包含多个嵌套对象或数组的单一结构,需要一次性读取整个文件才能解析。
- JSONL:每行都是一个独立的JSON对象,没有根级别的数组结构,每行就是一个数据记录。
JSONL适用场景:
- 当数据以行为单位独立存储,每行数据之间没有明确的分隔符时;
- 当需要逐行处理数据,以节省内存和提高处理速度时;
- 当数据量非常大,无法一次性加载到内存中时,JSONL提供一种流式处理数据的方式。
示例:
["Name", "Session", "Score", "Completed"]
{"may":{"include":"nested","objects":["and","arrays"]}}
JSONL数据在线校验器。
Python Pandas库读取JSONL文件:pandas.read_json(..., lines=True)
以Python为例,安装:pip install jsonlines
示例:
import jsonlines
import json# 读取jsonl文件
with open("data.jsonl", "r") as file:for line in file:json_obj = json.loads(line)# 对 JSON 对象进行处理print(json_obj["name"], json_obj["age"])# json文件转为jsonlines
with jsonlines.open(write_path, "w") as wfd:with open(read_path, "r", encoding='utf-8') as rfd:for data in rfd:data = json.loads(data) # 注意区别json.load()与json.loads()wfd.write(data)# jsonlines转为json文件
with jsonlines.open(read_path, "r") as rfd:with open(write_path, "w", encoding='utf-8') as wfd:for data in rfd:json.dump(data, wfd, indent=4, ensure_ascii=False)
ijson
一个流式处理JSON数据的Python库,可有效地处理大型JSONL文件。
安装:pip install ijson
import ijsonwith open("data.jsonl", "rb") as file:# 使用ijson.items函数读取JSONL文件中的每个JSON对象for json_obj in ijson.items(file, "item"):print(json_obj)
NDJSON
Newline Delimited JSON缩写,用换行符分隔的JSON,GitHub,778 Star,31 Fork。NDJSON和JSONL是同一格式的两种名称。文件后缀名为.ndjson
。
特点:
- 无顶层结构:整个文件本身不是一个有效的JSON数组或对象。不能用单个
JSON.parse()
去解析整个文件; - 编码:通常使用
UTF-8
编码。
官方收录支持NDJSON格式的不同语言的类库。这个主域名真牛逼。慎点。
特征 | JSON Lines(.jsonl ) | Newline Delimited JSON(.ndjson ) |
---|---|---|
每行内容 | 规范允许是JSON数组,但对象是主流 | 通常是JSON对象 |
MIME类型 | 没有官方注册的MIME类型 | 有一个注册的MIME类型:application/x-ndjson |
社区 | 数据科学、机器学习、日志文件 | 特定API(如Elasticsearch)、流处理 |
BSON
在初识MongoDB时接触到BSON,Binary JSON。官方规范,官方收录各大主流语言实现工具或类库。
一种用于数据存储和网络传输的二进制格式,尤其是在MongoDB数据库中被广泛使用。BSON是对JSON的扩展,其主要目的是通过二进制编码,实现更高效的数据存取,同时支持比JSON更多的复杂数据类型,例如日期(Date)和二进制数据(BinData)。
优势:
- 性能:比JSON具有更高的遍历速度和更低的存储空间占用;
- 数据类型:支持JSON所不包含的日期和二进制等类型;
- 灵活性:是一种模式不固定的存储格式,可有效描述非结构化和结构化数据。
JSONB
一种PostgreSQL特有的、存储半结构化数据的二进制格式数据类型,与JSON类型主要区别在于效率和格式:JSONB在存储时会解析并转换成二进制,不保留冗余的空格、键的顺序及重复的键(只保留最后一个),因此读取和操作速度快但写入稍慢;而JSON类型存储的是原始文本,保留所有细节,写入快但读取和操作时需要重新解析,速度较慢。
特点
- 二进制格式:JSONB数据以分解的二进制格式存储,而不是原始文本;
- 高效处理:由于是二进制格式,处理速度比JSON类型快很多,不需要在每次操作时都进行解析;
- 空间优化:JSONB会删除不必要的空格,并保留重复键时只保留最后一个值,有助于减少存储空间;
- 索引支持:在JSONB数据上可以建立索引,进一步提高查询效率;
- 适用于半结构化数据:非常适合存储需要灵活性、但又需要强大查询能力的半结构化数据。
对比JSON
- JSON:存储原始的JSON文本,会保留输入的格式、空格、重复的键(按顺序保留)以及键的顺序;
- JSONB:存储的是经过解析和优化处理后的二进制格式,不保留原始格式细节,写入稍慢,但读取和操作快。
JSONC
JSON with Comments缩写,官网,GitHub。
注意:json-c,3.2K Star,1.1K Fork,这个GitHub仓库并不是JSONC的官方仓库,而是用C语言来实现JSON。
一个比JSON5更轻量级的扩展,主要目的就是支持注释。基本上就是标准的JSON,但额外允许使用//
和/**/
来添加注释;不像JSON5那样引入单引号、尾随逗号等大量新语法。
推荐使用.jsonc
文件后缀名;对于.json
文件,若在第一行有如下模式声明行也支持:
// -*- mode: jsonc -*-
或
// -*- jsonc -*-
对于Java语言,以Jackson
库为例,在配置类里添加如下一行代码即可支持解析JSONC文件:
JsonFactory.enable(JsonReadFeature.ALLOW_JAVA_COMMENTS)
对于其他语言,官网列举一些支持JSONC的工具类库,也可在GitHub搜索其他实现。
比如:
- JS/TS:微软实现node-jsonc-parser
- Python:json-with-comments
- GO:jsonc
Python类库安装:pip install json-with-comments
示例:
import jsoncprint(jsonc.loads("{// comment \n}")) # {}
print(jsonc.loads("{/* comment */}")) # {}
print(jsonc.loads('{"spam": "ham // egg" /* comment */}')) # {'spam': 'ham // egg'}
print(jsonc.loads('{"spam": /* comment */"ham /* egg */"}')) # {'spam': 'ham /* egg */'}
和使用json
模块一样没区别。
JSONP
参考跨域、JSONP、CORS、Spring、Spring Security解决方案。
JSON with Padding,JSON的一种使用模式,可让网页从别的域名(网站)那获取资料,即跨域读取数据。解决跨域问题的一种方法,
HOCON
Human-Optimized Config Object Notation缩写。
一个功能非常强大的配置文件格式,最初由Typesafe(现Lightbend)为Akka和Play Framework开发。
特点:HOCON也是JSON的超集,但比JSON5更进一步,支持:
- 注释、尾随逗号等JSON5特性;
- 变量替换/引用:可以在配置文件中引用其他配置项的值;
- 文件包含:可将一个配置文件拆分成多个,并通过
include
指令组合; - 更宽松的语法:例如可省略大括号、等号等。