Protobuf简介
简明扼要的说,protobuf是一种对结构化数据的序列化格式(形如JSON、XML),用于在数据通信、数据存储之中。protobuf是由Google设计开发,与开发平台及开发语言均无关。其特点在于灵活高效,序列化后的数据简单、轻便,序列化/反序列化过程耗时更短。
在使用Protobuf时,需要将待序列化的结构类型在“.proto“文件中进行标注声明。一个protocol buffer消息,包含有若干个key-value对。在一个消息内,每一个字段都包含有它的名字和它的数据类型。数据类型可以是数字、布尔型、字符串、比特串,甚至是其他的protocol buffer消息类型。对声明的消息字段,可以特别的声明该字段是可选字段(optional)还是必填字段(required)还是可重复字段(repeated)。以下是一个.proto文件的样例:
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;
}
在你已经定义好消息格式后,便可运行protocol buffer的编译器,将.proto文件编译成项目中可被访问的实体类了。在生成的实体类中,包含有对字段的控制方法(getter,setter),也包含有序列化/反序列化的方法。你可以在消息格式中添加新的字段,而不会导致破坏向后兼容性,老的数据流在进行反序列化时,会忽略新添加的字段。
每一个在消息定义中的字段都有一个唯一的数字标签,这个数字标签(tag)是用于标记在数字二进制编码形式下,该实体类字段所在的位置。需要注意的一点是,当tag的取值范围在[1,15]时,将会把数字标识和字段类型封装在一个字节内,如果tag的取值范围在[16,2047]范围内,将会封装在两个字节内。tag的最小取值为1,最大的取值为\(2^{29}-1\),但值得注意的是不能使用[19000,19999]内的数字,因为这些是由protocol内部使用。