JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于文本、易于读写,并支持多种数据结构。以下是常见的JSON格式及示例:
1. 简单对象(键值对)
{
"name": "Alice",
"age": 25,
"isStudent": true
}
2. 嵌套对象
{
"person": {
"name": "Bob",
"address": {
"city": "New York",
"zipcode": "10001"
}
}
}
3. 数组
["apple", "banana", "orange"]
4. 对象中包含数组
{
"fruits": ["apple", "banana"],
"colors": ["red", "yellow"]
}
5. 数组中的对象
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
6. 混合复杂结构
{
"class": "Math 101",
"students": [
{"name": "John", "grade": 90},
{"name": "Emily", "grade": 85}
],
"active": true
}
7. 特殊值(null/布尔值/数字)
{
"value1": null,
"value2": false,
"value3": 3.14
}
8. 空对象或空数组
{}
或
[]
9. JSON中的转义字符
{
"message": "Hello, \\\\"World\\\\"!\\\\nNew line."
}
注意事项:
- 键名必须用双引号
"
包裹(单引号无效)。 - 值可以是:字符串、数字、布尔值、对象、数组、
null
。 - 不支持注释、函数等JavaScript特有语法。
- [ ] 列表也是JSON
如果需要验证或格式化JSON,可以使用在线工具如 JSONLint。
[ 1,2,3]也属于JSON格式
验证规则:
- JSON 标准允许的顶级结构:
- 对象(
{}
键值对) - 数组(
[]
有序列表) ← 符合此例
- 对象(
- 值类型合法:数组中的元素是数字(
1
,2
,5
),属于JSON支持的原始类型(数字/字符串/布尔值/null
/对象/数组)。
其他合法JSON数组示例:
["a", "b", "c"] // 字符串数组
[true, false, null] // 布尔值和null
[[1, 2], {"x": 3}] // 嵌套混合结构
常见误区:
-
误区:JSON必须用
{}
包裹。纠正:JSON的顶级结构可以是对象 或数组(RFC 8259标准明确规定)。 -
非JSON示例:
[1, 2, 'unquoted'] # 非法!JSON字符串必须用双引号
快速验证工具:
-
在线校验:JSONLint
-
Python代码验证:
import json try: json.loads('[1, 2, 5]') # 无报错则合法 print("是合法JSON") except json.JSONDecodeError: print("非法JSON")
JSON和JSONL区别
JSON(JavaScript Object Notation)和 JSON Lines(JSONL/NDJSON) 是两种常见的数据格式,主要用于数据存储和交换。它们的主要区别在于结构、用途和存储方式。以下是详细对比:
1. 基本定义
格式 | 描述 |
---|---|
JSON | 单文件存储一个完整的结构化数据(对象或数组),适合表示复杂嵌套数据。 |
JSONL | 每行是一个独立的JSON对象,适合存储或流式传输大量记录(如日志)。 |
2. 核心区别
特性 | JSON | JSON Lines (JSONL) |
---|---|---|
文件结构 | 整个文件是一个对象或数组 | 每行是一个独立的JSON对象 |
可读性 | 适合人类阅读(格式化后) | 适合机器逐行处理(如日志流) |
扩展性 | 修改需解析整个文件 | 可直接追加新行(无需解析全文) |
错误处理 | 一处错误导致整个文件无效 | 单行错误不影响其他行 |
常见用途 | API响应、配置文件 | 日志文件、大数据处理(如ETL) |
3. 示例对比
JSON 示例
{
"users": [
{"id": 1, "name": "Alice", "active": true},
{"id": 2, "name": "Bob", "active": false}
]
}
JSONL 示例
{"id": 1, "name": "Alice", "active": true}
{"id": 2, "name": "Bob", "active": false}
4. 关键场景选择
- 用 JSON 当:
- 需要表示复杂嵌套结构(如配置文件)。
- 数据需要一次性完整加载(如API响应)。
- 用 JSONL 当:
- 处理大量独立记录(如日志、传感器数据)。
- 需要流式逐行读取/写入(避免内存压力)。
- 数据需要频繁追加(如实时日志收集)。
5. 技术细节
- JSONL 的别名:
NDJSON
(Newline-Delimited JSON)LDJSON
(Line-Delimited JSON) (三者基本等价,但某些工具可能有细微差异)
- JSONL 的规范:
- 每行必须是合法JSON(不能是纯字符串或注释)。
- 行间无逗号或换行符外的分隔符。
6. 常见工具支持
格式 | 相关工具 |
---|---|
JSON | 所有编程语言原生支持(如Python的json 模块、JavaScript的JSON.parse )。 |
JSONL | 需逐行处理(如Python的for line in file ),或专用库(如jsonlines )。 |
总结
- JSON 适合结构化、完整加载的数据。
- JSONL 适合流式、大规模记录级数据处理。
根据数据的使用场景(是否需要拆分、是否需流式处理)选择即可。
python 读取和保存JSON和JSONL文件
以下是使用 Python 读取和保存 JSON 和 JSONL(JSON Lines) 文件的完整代码示例,包含详细注释和常见操作:
1. JSON 文件操作
import json
# 示例数据(嵌套结构)
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "SQL"],
"address": {
"city": "Beijing",
"zipcode": "100000"
}
}
# 保存 JSON 文件
def save_json(file_path, data):
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False) # indent 美化格式
print(f"JSON 已保存至 {file_path}")
# 读取 JSON 文件
def load_json(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
# 测试
save_json('data.json', data)
loaded_data = load_json('data.json')
print("读取的JSON内容:", loaded_data)
2. JSONL 文件操作
# 示例数据(每行一个独立JSON对象)
data_lines = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True}
]
# 保存 JSONL 文件
def save_jsonl(file_path, data_lines):
with open(file_path, 'w', encoding='utf-8') as f:
for line in data_lines:
f.write(json.dumps(line, ensure_ascii=False) + '\\\\n') # 每行一个JSON
print(f"JSONL 已保存至 {file_path}")
# 读取 JSONL 文件
def load_jsonl(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return [json.loads(line.strip()) for line in f if line.strip()]
# 测试
save_jsonl('data.jsonl', data_lines)
loaded_lines = load_jsonl('data.jsonl')
print("读取的JSONL行数:", len(loaded_lines))
print("第一行内容:", loaded_lines[0])
3. 实际应用场景
场景1:处理API响应(JSON)
import requests
# 从API获取JSON数据
response = requests.get('<https://api.example.com/users>')
api_data = response.json() # 直接解析JSON
# 保存到本地
save_json('api_response.json', api_data)
场景2:逐行处理日志(JSONL)
# 模拟实时追加日志
new_log = {"timestamp": "2023-01-01T12:00:00", "event": "login", "user": "Alice"}
with open('logs.jsonl', 'a', encoding='utf-8') as f: # 'a' 表示追加模式
f.write(json.dumps(new_log) + '\\\\n')
# 读取日志文件
logs = load_jsonl('logs.jsonl')
print("最新日志:", logs[-1])
4. 注意事项
-
编码问题:始终指定
encoding='utf-8'
避免乱码。 -
错误处理:添加
try-catch
处理损坏文件:try: data = load_json('broken.json') except json.JSONDecodeError as e: print(f"文件解析失败: {e}")
-
性能优化:
- 大JSON文件用
ijson
库流式解析。 - 大JSONL文件逐行读取(避免内存爆炸)。
- 大JSON文件用
借助DS生成。