Protobuf学习笔记(一)

26 篇文章 1 订阅

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_outobjc_outruby_outphp_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 TypeNotesC++ TypeJava TypePython Type[2]Go TypeRuby TypeC# TypePHP TypeDart Type
double doubledoublefloatfloat64Floatdoublefloatdouble
float floatfloatfloatfloat32Floatfloatfloatdouble
int32使用可变长度编码。int32intintint32Fixnum or Bignum (as required)intintegerint
int64使用可变长度编码。int64longint/long[3]int64Bignumlonginteger/string[5]Int64
uint32使用可变长度编码。uint32int[1]int/long[3]uint32Fixnum or Bignum (as required)uintintegerint
uint64使用可变长度编码。uint64long[1]int/long[3]uint64Bignumulonginteger/string[5]Int64
sint32使用可变长度编码。int32intintint32Fixnum or Bignum (as required)intintegerint
sint64使用可变长度编码。int64longint/long[3]int64Bignumlonginteger/string[5]Int64
fixed32始终为四个字节。uint32int[1]int/long[3]uint32Fixnum or Bignum (as required)uintintegerint
fixed64始终为八个字节。uint64long[1]int/long[3]uint64Bignumulonginteger/string[5]Int64
sfixed32始终为四个字节。int32intintint32Fixnum or Bignum (as required)intintegerint
sfixed64始终为八个字节。int64longint/long[3]int64Bignumlonginteger/string[5]Int64
bool boolbooleanboolboolTrueClass/FalseClassboolbooleanbool
string字符串必须始终包含UTF-8编码或7位ASCII文本,并且不能超过232。stringStringstr/unicode[4]stringString (UTF-8)stringstringString
bytes

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

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

stringByteStringstr[]byteString (ASCII-8BIT)ByteStringstringList

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值