转自https://www.dazhuanlan.com/2020/01/19/5e2402ee05077/
protobuf
发表于 2020-01-19 | 分类于 后端 | 没有评论
Protobuf: Google Protocol Buffer,是 Google 公司内部的混合语言数据标准,用于 RPC 系统和持续数据存储系统。
proto3 与 proto2 的区别
proto3 比 proto2 支持更多语言(如Go、Ruby、JavaNano等),去掉了一些复杂的语法和特性,更强调约定而弱化语法。下面列举几点 proto3 与 proto2 的不同点:
1、proto 文件开头第一行必须指定版本:syntax = "proto3";
,而在 proto2 中,可以写成 syntax = "proto2";
或者不写;
2、字段规则移除了 “required”,将并把 “optional” 改名为 “singular”;
3、“repeated” 字段默认采用 packed 编码,而在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式;
4、移除了 default 选项,在 proto2 中,可以使用 default 选项为某一字段指定默认值,而在 proto3 中,字段的默认值只能根据字段类型由系统决定;
5、增加了 JSON 映射特性
……
protobuf编程
由于我的开发环境是Ubuntu 1604, 所以我这里编写示例代码将使用 proto2。protobuf是支持嵌套类型的,如下所示为 Protocol Buffers 官方文档提供的嵌套类型示例 Protocol Buffers 官方文档(proto文件添加注释和C/C++一样,使用 //
或 /* ... */
语法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } |
示例代码将介绍两种语言的 protobuf 使用,C++和Python,对于C++,编译器会根据每个.proto文件生成一个.h和一个.cc文件,并为文件中描述的每种消息类型提供一个类。而对于Python则不同,Python编译器生成一个模块,其中包含每个消息类型的静态描述符,.proto然后与元类一起使用,以在运行时创建必要的Python数据访问类。
C++示例
在动手编写代码之前,我们需要先安装编译依赖,执行如下命令:
1 | $ sudo apt install libprotobuf-dev protobuf-compiler |
C++ 示例代码的myinfo.proto文件的内容如下:
1 2 3 4 5 6 7 8 | syntax = "proto2"; package com.xiaoming.protobuf; message BufferMessage{ required int64 id = 1; required string name = 2; optional int32 opt = 3; } |
使用 protoc 命令根据 .proto 文件生成对应的 .pb.cc 和 .pb.h 文件,格式如下:
protoc -I=输入目录 --cpp_out=输出目录 xxx.proto
比如执行protoc -I=./ --cpp_out=./ myinfo.proto
则生成 myinfo.pb.cc 和 myinfo.pb.h。
源码中 test_in.c 的作用是序列化,并将序列化的内容写入文件中,而 test_out.c 的作用则是反序列化,读取 test_in.c 写入文件中的内容并反序列化。
具体编译情况见Makefile文件,编译和运行如下:
1 2 3 | make ./test_in ./test_out |
Python示例
安装依赖,执行如下命令:
1 | $ sudo apt install python-protobuf |
Python 示例代码的myinfo.proto文件的内容如下(该文件根据上面提到的 Protocol Buffers 官方文档中提供的嵌套类型示例改写而来):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | syntax = "proto2"; package com.xiaoming.protobuf; message ClassMate{ required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType{ MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber{ required string number = 1; required PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AlumniBook{ repeated ClassMate mate = 1; } |
使用 protoc 命令根据 .proto 文件生成对应的 .py 文件,格式如下:
protoc -I=输入目录 --python_out=输出目录 xxx.proto
比如执行 protoc -I=./ --python_out=./ myinfo.proto
则生成 myinfo_pb2.py 文件。
源码中 test_in.py 的作用是序列化,并将序列化的内容写入文件中,test_out.py 的作用则是反序列化,读取 test_in.py 写入文件中的内容并反序列化。
运行命令如下:
1 2 | python test_in.py 1.log python test_out.py 1.log |
HTML5 player for raw h.264 streams
© - 2020 大专栏|粤ICP备18064926号-2