深入ProtoBuf

408 阅读3分钟

一、什么是ProtoBuf?

ProtoBuf的全称是Protocol Buffers。它是Google公司开发的一种数据描述语言,用于描述一种轻便高效的结构化数据存储格式。

ProtoBuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以 K-V 的方式来存储数据,对消息的版本兼容性非常强,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

二、JSON 、XML 与 ProtoBuf 的区别?

JSON注重数据结构化,键值对方式,可读性高易于理解,适用范围广,数据保存方式为文本保存,多用于web项目及Api交互场合;XML在webservice中应用最为广泛,但是相比于json,它的数据更加冗余,因为需要成对的闭合标签,数据保存方式为文本保存;ProtoBuf后起之秀,注重数据序列化、效率、空间、速度,数据保存方式为二进制。

总结:

  1. XML、JSON、ProtoBuf 都具有数据结构化和数据序列化的能力
  2. XML、JSON 更注重数据结构化,关注人类可读性和语义表达能力。ProtoBuf 更注重数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足(为保证极致的效率,会舍弃一部分元信息
  3. ProtoBuf 的应用场景更为明确,XML、JSON 的应用场景更为丰富。

三、定义message

message消息是proto文件中最基本的元素体,用来对消息进行描述。

定义消息使用message关键字。如下:

syntax = "proto3";

message Person {
  int32 id = 1;
  string name = 2;
  string email = 3;
}

1、指定编译版本

syntax = "proto3"; 
// 必须是文件中非空非注释行的第一行
// 使用proto3语法 如果省略protocol buffer编译器默认使用proto2语法。

2、指定包名

syntax = "proto3";


package protoOne;
// 定义包名
// 多个proto文件多个指定为同一个包名

3、指定字段类型

message Person {
  int32 id = 1;
  string name = 2;
  string email = 3;
}

message的所有字段都是标量类型:id为整数,name、email为字符串。您也可以为字段指定复合类型,包括枚举或其他消息类型。

标量类型:

4、指定字段规则

您指定消息字段是以下之一:

  • required: 格式正确的消息必须恰好具有此字段之一。
  • optional:格式正确的消息可以有零个或一个此字段(但不能超过一个)。
  • repeated:该字段可以在格式良好的消息中重复任意次数(包括零次)。重复值的顺序将被保留。
message Person {
  required int32 id = 1;
  optional string name = 2;
  optional string email = 3;
}

5、指定字段编号

在message定义中每个字段都有一个唯一的编号,这些编号被用来在二进制消息体中识别你定义的这些字段。

注意在将message编码成二进制消息体时字段编号1-15将会占用1个字节,16-2047将占用两个字节。所以在一些频繁使用用的message中,你应该总是先使用前面1-15字段编号。

你可以指定的最小编号是1,最大是2E29 - 1(536,870,911)。其中19000到19999是给protocol buffers实现保留的字段标号,定义message时不能使用。

6、嵌套消息

消息类型可以被定义和使用在其他消息类型中。

message Person {
  required int32 id = 1;
  optional string name = 2;
  optional string email = 3;

  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
}

7、生成代码

Protobuf 支持多种不同的编程语言。对于每种编程语言,您可以在相应的源目录中找到有关如何为该特定语言安装 protobuf 运行时的说明。

参考文献

Protocol Buffers