Protobuf学习笔记(一)

  • Post author:
  • Post category:其他


Protobuf(

Protocol Buffer)

是谷歌开源的性能优异、跨语言、跨平台的

序列化库


一, 发展过程:


proto1:

2001年,Protobuf首先在Google内部创建,把它称之为

proto1

,一直以来在Google的

内部使用

,其中也不断的演化。


proto2:

Protobuf的开发者重写了Protobuf的实现,保留了proto1的大部分设计。

开源

的proto2不依赖任何的Google的库,代码也相当的清晰。2008年7月7日,Protobuf被

公布出来

。Protobuf得到了大家的广泛的关注, 逐步地得到了大家的认可,很多项目采用Protobuf进行消息的通讯,还有基于Protobuf的

微服务框架GRPC


proto3:

2016年推出了Proto3。 Proto3简化了proto2的开发,提高了开发的效能,但是也带来了

版本不兼容

的问题。目前Protobuf的稳定版本是3.9.2,于2019年9月23日发布。


二, 序列化和反序列化:


序列化

(serialization、marshalling)的过程是指将

数据结构或者对象

的状态转换成可以

存储(比如文件、内存)或者传输的格式(比如网络)


反序列化

(deserialization、unmarshalling)就是反向操作的过程。


XML

是一种基于文本的编码方式,易于阅读和理解,但是失去了紧凑的基于字节流的编码的优势。


JSON

是一种更轻量级的基于文本的编码方式,经常用在client/server端的通讯中。


YAML

类似JSON,新的特性更强大,更适合人类阅读,也更紧凑。

其他的序列化格式,如Thrift、Avro、BSON、CBOR、MessagePack等等。


Protobuf

支持很多语言,比如C++、C#、Dart、Go、Java、Python、Rust等,同时也是跨平台的。


三,proto3使用demo:


创建一个demo_example.proto 其内部代码如下:

syntax = "proto3";

package vddp_proto.property_service;

message SetReq {
    string str_signal_name = 1;
    uint32 g_signal_value = 2;
    float f_signal_value = 3;
}

【syntax = “proto3”; 】指定protobuf的版本,这里是以proto3格式定义。如果没有指定,默认以proto2格式定义。

【package vddp_proto.property_service; 】 定义proto的包名,包名可以避免对message 类型之间的名字冲突,同名的Message可以通过package进行区分。

【message SetReq {


string str_signal_name = 1;

uint32 g_signal_value = 2;

float f_signal_value = 3;

} 】  定义了一个message类型: SetReq , 它包含三个字段str_signal_name 、g_signal_value 、f_signal_value ,它会被protoc编译成不同的编程语言的相应对象。

字段是以

[ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"

格式定义的。

这个demo是一个简单的例子,采用了

type fieldName "=" fieldNumber

格式定义的。【注:后面要去学习 复杂的字段定义】


编译proto:

在当前的目录下执行【

protoc -I=. -I/user/local/include -I=$(GOPATH)/src –go_out=. demo_example.proto】

, 可以将这个proto编译成Go的代码,因为这里我们使用了

go_out

输出格式。


【-I】

指定protoc的搜索import的proto的文件夹。【demo中

-I=. -I/user/local/include -I=$(GOPATH)/src

搜索了三个路径】


【–go_out=.

】使用

go_out

输出格式,将proto编译成Go的代码,生成的代码指定放在本地文件夹【.】中。另外

cpp_out

用来生成C++代码,

java_out

产生Java代码,

python_out

产生python代码,类似地还有

csharp_out



objc_out



ruby_out



php_out

等参数。


四,proto更多的文本定义:

定义proto的版本:【syntax = “proto3”;】

引入其它proto文件:【import “other.proto”;】

定义proto的包名:【package signal.bar;】

定义option:【option java_package = “com.example.foo”;】

option可以用在proto的scope中,或者message、enum、service的定义中。

可以是Protobuf定义的option,或者自定义的option。

option的定义格式是【

"option" optionName "=" constant ";"】


五,proto中字段可以使用的数据类型:

  • 数字类型: double、float、int32、int64、uint32、uint64、sint32、sint64: 存储长度可变的浮点数、整数、无符号整数和有符号整数
  • 存储固定大小的数字类型:fixed32、fixed64、sfixed32、sfixed64: 存储空间固定
  • 布尔类型: bool
  • 字符串: string
  • bytes: 字节数组
  • messageType: 消息类型
  • enumType:枚举类型

proto中数据类型与其他语言的对应关系:

.proto Type Notes C++ Type Java Type Python Type[2] Go Type Ruby Type C# Type PHP Type Dart Type
double double double float float64 Float double float double
float float float float float32 Float float float double
int32 使用可变长度编码。 int32 int int int32 Fixnum or Bignum (as required) int integer int
int64 使用可变长度编码。 int64 long int/long[3] int64 Bignum long integer/string[5] Int64
uint32 使用可变长度编码。 uint32 int[1] int/long[3] uint32 Fixnum or Bignum (as required) uint integer int
uint64 使用可变长度编码。 uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5] Int64
sint32 使用可变长度编码。 int32 int int int32 Fixnum or Bignum (as required) int integer int
sint64 使用可变长度编码。 int64 long int/long[3] int64 Bignum long integer/string[5] Int64
fixed32 始终为四个字节。 uint32 int[1] int/long[3] uint32 Fixnum or Bignum (as required) uint integer int
fixed64 始终为八个字节。 uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5] Int64
sfixed32 始终为四个字节。 int32 int int int32 Fixnum or Bignum (as required) int integer int
sfixed64 始终为八个字节。 int64 long int/long[3] int64 Bignum long integer/string[5] Int64
bool bool boolean bool bool TrueClass/FalseClass bool boolean bool
string 字符串必须始终包含UTF-8编码或7位ASCII文本,并且不能超过232。 string String str/unicode[4] string String (UTF-8) string string String
bytes

May contain any arbitrary sequence of bytes no longer than 232.

可以包含不超过232个任意字节序列。

string ByteString str []byte String (ASCII-8BIT) ByteString string List



版权声明:本文为Code_DZhangTeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。