最近的工作中需要用到protocol buffers(以下简称protobuf),于是就去学习了一把,真的是收益颇丰啊。

1、什么是protobuf

protobuf是谷歌开源的一种多语言、多平台和可扩展的结构化数据序列化机制,可以联想到我们熟悉的xml和json等,但是protobuf速度更快、体积更小和使用起来更加便捷。你只需要定义一次如何将数据结构化,然后就可以使用其编译器生成源码(生成相应的类),接下来你就可以非常方便地读、写结构化的数据。你甚至可以在不破坏已经编译部署的旧的格式的程序的前提下,更新你的数据结构(向前、向后兼容)。


2、protobuf是如何工作的?

你可以通过定义protobuf信息类型文件(xxx.proto)来指定希望序列化的信息的结构,每一个protobuf信息文件是一个小的逻辑信息记录,包含有一些列key-value。下面是一个简单的例子。

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的信息格式非常简单,每一个信息类型有一个或多个唯一的编号的域,每一个域都有一个名字和一个值类型,其中的值的类型可以是数字、bool值、字符串、原始字节,甚至可以是其他的protobuf信息类型(即,protobuf信息可以嵌套)。这使得你可以分层地结构化你的数据。你也可以指定域的为可选的、必须的或者重复的。更多的关于xxx.proto文件的域的说明个可以参看 Protocol Buffer Language Guide
一旦你定义了自己的protobuf信息(即,xxx.proto文件),你就可以运行protobuf编译器,根据.proto文件生成对应语言的数据访问类(目前支持C++、C#、Go、Java、Python)。这些数据访问类提供了访问每个域的便捷的方法(例如,name()和set_name()),包括序列化和解析整个数据结构的方法。下面以C++语言为例,基于上面的.proto文件,通过protobuf编译器将生成Person类,你就可以在自己的应用中使用该Person类来填充、序列化和修改Person的protobuf信息。例子如下:

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream output("myfile", ios::out | ios::binary);
person.SerializeToOstream(&output);
你也可以从序列化后的流中解析出数据,示例如下:
fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

你可以在不破坏向后兼容性的前提下,自由地增加新的域到你的protobuf信息中,旧的二进制文件在解析式会忽略新增加的域。

3、如何开始使用protobuf?

(1)下载并安装protobu编译器安装包

下载地址:https://developers.google.cn/protocol-buffers/docs/downloads
(2)参照如下地址中的示例,可以创建一个测试程序

示例链接:https://developers.google.cn/protocol-buffers/docs/tutorials



参考文献:

【1】https://developers.google.cn/protocol-buffers/

【2】github地址:https://github.com/google/protobuf

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐