将 JSON 文件转换为 Protobuf 格式

当完成 JSON 文件后,我们需要将它转换为 Protobuf 格式,使用这种格式,可以更高效的存储和传输文件。它特别适合大数据的场景。

现在通过 Python 将 JSON 文件转换为 Protobuf 格式。

1,定义 Protobuf 结构,创建一个.proto 文件(如 data.proto)来定义数据结构:

syntax = "proto3";

message DataItem {
  string id = 1;
  string name = 2;
  string kw = 3;
  bool lock = 4;
  string category = 5;
  string label = 6;
  int32 grade = 7;  // 新添加的字段
}

message DataList {
  repeated DataItem items = 1;
}

2,生成 Python 代码,安装 Protobuf 编译器并生成代码:

# 安装编译器 (需提前安装 protobuf 编译器,可从 https://github.com/protocolbuffers/protobuf/releases 下载)
protoc --python_out=. data.proto

# 安装 Python 依赖库
pip install protobuf

执行后会生成 data_pb2.py 文件(用于操作 Protobuf)。

3,编写转换脚本,这是实际的处理逻辑,创建 json_to_protobuf.py 文件:

import json
from data_pb2 import DataList

def json_to_protobuf(json_path, proto_path):
    # 读取 JSON 数据
    with open(json_path, "r", encoding="utf-8") as f:
        json_data = json.load(f)

    # 创建 Protobuf 对象
    proto_data = DataList()

    # 填充数据
    for item in json_data:
        proto_item = proto_data.items.add()
        proto_item.id = item.get("id", "")
        proto_item.name = item.get("name", "")
        proto_item.kw = item.get("kw", "")
        proto_item.lock = item.get("lock", False)
        proto_item.category = item.get("category", "")
        proto_item.label = item.get("label", "")
        proto_item.grade = item.get("grade", 1)  # 默认值 1

    # 序列化并保存
    with open(proto_path, "wb") as f:
        f.write(proto_data.SerializeToString())
    print(f"转换完成!输出文件: {proto_path}")

if __name__ == "__main__":
    json_to_protobuf("data.json", "data.bin")

4,运行脚本将生成 data.bin 文件,该文件为 Protobuf 格式的二进制文件。

python json_to_protobuf.py

5,我们也需要验证生成的文件是否可读?

使用如下脚本可以读取 Protobuf 文件并检查数据:

from data_pb2 import DataList

def read_protobuf(proto_path):
    data = DataList()
    with open(proto_path, "rb") as f:
        data.ParseFromString(f.read())
    for item in data.items:
        print(f"ID: {item.id}, Grade: {item.grade}")

read_protobuf("data.bin")

需要注意的事项:确保 JSON 字段类型与 Protobuf 定义一致,JSON 中缺失字段时,使用.get(key,default)设置默认值。若后续修改数据结构,一定要同步更新.proto 文件并重新生成代码。