protobuf-介绍篇

来源:互联网 发布:c语言常用的英文单词 编辑:程序博客网 时间:2024/06/07 08:59

What are protocol buffers?


protobuf 是 protocol buffers的简称,它是结构体数据序列化的协议方法,简单、灵活、高效、自动,更重要的是它垮平台、支持多种语言(目前支持java、c++、python)。类似 XML,但是比 xml 更小、更快速、更简单。你可以一次定义特定的数据结构,然后编译生产特定的语言代码对象(例如java),然后在这种语言下你很方便的实现对这个数据结构进行读和写,并且在数据流中传输,然后实现跨语言快平台的读写操作。


How do they work?


1 按照 protobuf 的语法定义你的数据结构,保存为 .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;}

数据结构很简单,关于 protobuf 定义语法细节请参考:https://developers.google.com/protocol-buffers/docs/proto

一旦你定义好了你的 protobuf messages (数据结构),你可以使用 protobuf 的编译器将 .proto 文件编译生产制定语言的类文件,这个文件的成员变量和类型和 .proto 文件里面定义的对应。例如,如果你选择的是 c++ 语言,运行编译器编译上面的 .proto 文件,会生成一个叫做 Person 的类。然后你可以使用这个类进行序列化/反序列化的操作。例如:

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;
图解:


为啥不用 XML 就行了


关于数据结构的序列化,protobuf 有很多优点。
  • 结构更简单
  • 占用空间比 XML 小3~10倍
  • 速度比 XML 快10~20倍
  • 比 XML更少参数歧义
  • 生产语言原生数据对象更简单

例如:现在定义一个 Person 对象,包含 name 和 email 两个字段。用 XML 定义为:

  <person>    <name>John Doe</name>    <email>jdoe@example.com</email>  </person>
使用 protobuf 定义为:
# Textual representation of a protocol buffer.# This is *not* the binary format used on the wire.person {  name: "John Doe"  email: "jdoe@example.com"}
当上面的结构编码成 protobuf 的二进制格式(上面的文本格式只是为了便于人理解和调试,最终回编译成机器能理解的二进制格式)之后,上面的数据大约九占 28个字节的长度,解析速度达到100~200纳秒;而上面的 XML 格式至少占用69个字节以上,而且解析速度为5000~10000纳秒。

再看看这解析上面的便利性。protobuf 使用很简单,语言对象的使用,例如:

cout << "Name: " << person.name() << endl;cout << "E-mail: " << person.email() << endl;
而 XML 的解析:
cout << "Name: "       << person.getElementsByTagName("name")->item(0)->innerText()       << endl;cout << "E-mail: "       << person.getElementsByTagName("email")->item(0)->innerText()       << endl;
虽然 proto buf 有这么多优点,但也不是任何场合下它都比 XML 好。例如在基于文本文档模型的应用中它就不是太好用。在一个消息定义模型的应用中 protobuf 的使用意义更大。

文章参考:https://developers.google.com/protocol-buffers/docs/overview

-》下篇文章介绍 protobuf 编译器的安装。

0 0