前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >json和pb文件的互换及文件压缩

json和pb文件的互换及文件压缩

原创
作者头像
languageX
发布2022-12-01 09:50:04
1.9K0
发布2022-12-01 09:50:04
举报
文章被收录于专栏:计算机视觉CV计算机视觉CV

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

在数据传输过程中,基于性能我们通常需要将json文件转为pb文件传输。本文就主要介绍json和pb文件相互转换的流程。

安装protobuf

1. 安装protobuf

下载源码 https://github.com/protocolbuffers/protobuf/releases

下载压缩包后进行解压和安装

tar -zxvf protobug-all-3.19.0.tar.gz
cd protobuf-3.19.0 && ./configure && make && make check && sudo make install 

安装成功后可以通过protoc --version校验是否安装成功。

2. python安装protobuf

pip3 install protobuf

安装完成之后能成功导入 google.protobuf表示成功。

import google.protobuf

编写proto文件

json和pb文件转换,首先需要有一个proto文件,主要定义需要处理的数据的结构,也就是

定义你要的消息和消息中的各个字段及其数据类型。

我们需要对着要处理的json文件的格式来编写proto,纯手写proto文件是个费时和麻烦的事情,有些工具可以提高我们写proto的效率

https://json-to-proto.github.io/

简单举例

如果json文件相对复杂或者格式不规范,可能会引起后续转换时的问题,可以根据提示调整生成的proto文件,我主要遇到的问题是array of dissimliar objects问题, 需要修改json文件格式。

如果使用其他的在线转换工具,可能会遇到:没有加分号,索引不是从1开始,添加了required关键字等问题。

使用python对json和pb转换

根据以上工具,我们已经有了一个proto文件test.proto,下面我们利用protoc生成一个python类。

protoc  --python_out=. test.proto  

能够生成test_pb2.py文件。

为了方便转换,我们使用简单的json文件格式做实验~

json文件:

{
"class1":{
"key1":3.14,
"key2":"test",
"key3":[1,2,3,4]
}
}

test.proto:

syntax = "proto3";

message TestMessage {

    message Class1 {
        double key1 = 1;
        string key2 = 2;
        repeated uint32 key3 = 3;
    }

    Class1 class1 = 1;
}

生成test_pb2.py

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: test.proto
"""Generated protocol buffer code."""
 ...
 ...
DESCRIPTOR = _descriptor.FileDescriptor(
  name='test.proto',
  package='',
  syntax='proto3',
  serialized_options=None,
  create_key=_descriptor._internal_create_key,
  ...
  ...
  TestMessage = _reflection.GeneratedProtocolMessageType('TestMessage', (_message.Message,), {
...
...
# @@protoc_insertion_point(module_scope)

接下来我们就可以对json和pb文件进行相互转换了。

from example.test_pb2 import TestMessage
from google.protobuf import json_format
import json

msg = TestMessage()
def pb_to_json(pb_str):
    """将pbstring转化为jsonString"""
    json_str=json_format.MessageToJson(pb_str)
    return json_str

def json_to_pb(json_str):
    """将jsonString转化为pbString"""
    pb_str = json_format.Parse(json.dumps(json_str), msg)
    return pb_str



if __name__ == '__main__':
    json_obj={"class1":{"key1":3.14,"key2":"test","key3":[1,2,3,4]}}
    pb_str=json_to_pb(json_obj)
    print("json_to_pb request---\n",pb_str)
    print(type(pb_str))
    with open('test.pb', 'wb') as fb:
    # 写.pb文件
        print("json_to_pb write---\n",type(pb_str.SerializeToString()))
        fb.write(pb_str.SerializeToString())

    json_str = pb_to_json(pb_str)
    print("pb_to_json request---\n",json_str)
    print(type(json_str))
    with open('test.json', 'w') as fb:
    # 写json文件
        fb.write(json_str)

得到输出

json_to_pb request---
 class1 {
  key1: 3.14
  key2: "test"
  key3: 1
  key3: 2
  key3: 3
  key3: 4
}

<class 'test_pb2.TestMessage'>
json_to_pb write---
 <class 'bytes'>
pb_to_json request---
 {
  "class1": {
    "key1": 3.14,
    "key2": "test",
    "key3": [
      1,
      2,
      3,
      4
    ]
  }
}
<class 'str'>

我们再看看生成的文件大小

可以看出pb文件只占json文件的20%。

对pb文件的进一步压缩

如果想进一步压缩pb,我们还可以使用一些压缩工具

zlib:

def compress_zlib(infile, dst, level=9):
    infile = open(infile, 'rb')
    dst = open(dst, 'wb')
    compress = zlib.compressobj(level)
    data = infile.read(1024)
    while data:
        dst.write(compress.compress(data))
        data = infile.read(1024)
    dst.write(compress.flush())

lz4:

lz4 test.pb

gzip

gzip frame_d2f.pb

当然压缩率要根据实际数据,我只是介绍这些工具的使用。

从压缩文件大小来看,本文简单实例就不适合使用这些压缩工具。

参考:

https://blog.csdn.net/u013421629/article/details/114022392

https://www.cnblogs.com/smileyes/p/9797258.html

https://github.com/protocolbuffers/protobuf/releases

https://blog.csdn.net/DinnerHowe/article/details/79805250

https://www.cnblogs.com/xueweihan/p/10167924.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装protobuf
  • 编写proto文件
  • 使用python对json和pb转换
  • 对pb文件的进一步压缩
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档