Protocol Buffer开发向导

开发者向导
欢迎阅读Google Protocol Buffers开发者向导,Protocol Buffers是一个跨语言、跨平台、可扩展的序列化数据结构,通常用于通信协议,数据存储等。

本文档是为在他们自己的应用程序中使用Protocol Buffers的Java、C++以及Python开发所写。本文(综述)介绍了Protocol Buffers协议以及需要准备些什么。你可以浏览此教程或者深入Protocol Buffers的编码API参考手册也包含三个语言版本(Java/C++/Python译者注),另外还有为编写.proto文件所准备的语言类型说明.

What are protocol buffers?

Protocol Buffers是一个灵活高效自动化的序列化数据结构----类似XML,但是更小更快,更简单。你仅需要定义你需要的数据怎么样结构化一次,即可用多种语言使用特殊生成的源码来轻松读写你需要的数据,并且序列化或者从数据流中反序列化。你甚至可以不中断已部署的程序,来更新你需要的数据结构,使之兼容旧版格式。
How do they work?
你通过在.proto文件中定义Protocol Buffers message类型,来声明你需要的序列化信息是怎么样结构组织的。每一个Protocol Buffers Message都是一个包含了一系列键值对的小的信息的逻辑记录。以下是.proto文件的一个基础范例,来演示其如何定义一个包含了关于人的Message。
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;
}


如你所见,Message的格式是简单的,每一个message类型有一个或者多个以数字唯一的标记的字段,每一个字段都有一个名字和值类型。值类型可以是数字(integer或者是floating-point),booleans,strings,或者bytes,甚至可以是其他Protocol Buffers message类型。这样可以允许你组织你的数据的继承关系。你可以声明候选字段(optional fields),必须字段(required fields),以及重复字段(repeated fields)。你可以在如下 Protocol Buffer Language Guide中找到更多关于编写.proto文件的信息。

一旦你定义了你的messages,你可以运行Protocol Buffers编译器为你的程序中的.proto文件生成类以及其中的数据。类为每个字段提供了简单的访问器(accessors),例如query()和set_query()。同时提供了序列化/解析整个数据为/自bytes数据流。例如,如果你选择C++开发,运行编译器编译以上的例子(person),会产生一个名为Person的类。你可以使用此类来修改(populate),序列化(serialize),读取(retrieve)Person的Protocol Buffer messages。你可以编写类似下面的代码

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);

然后,用以下方式读写messages

fstream input("myfile", ios::in | ios::binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

你可以增加一个新的字段到你个messages结构中,而无需担心破坏向后兼容性;此时解析原有二进制数据会采用简单的策略忽略掉新的字段。因而如果你在通信协议中使用Protocol Buffers的数据格式,你能够扩展你的协议而无需担心会导致现有程序的代码无法兼容。
你可以在以下  API Reference section中找到完整使用Protocol Buffers生成的类的参考手册,同时能够在如下 Protocol Buffer Encoding的链接获得更多Protocol Buffer Messages是编码的信息。


Why not just use XML?
和XML相比,在序列化结构化数据方面Protocol buffers有许多优势。Protocol buffers:
·更简单
·压缩3-10倍的大小
·速度2-100倍快
·语义更清晰
·能生成编程友好的数据访问类
例如,假设你想创建一个包含name和Email的person。在XML中,你需要

  <person>
    <name>John Doe</name>
    <email>jdoe@example.com</email>
  </person>

与此相应的 protocol buffer message(.proto文件中的 文本格式protocol buffer

# Textual representation of a protocol buffer.
# This is *not* the binary format used on the wire.
person {
  name: "John Doe"
  email: "jdoe@example.com"
}

当消息被编码成 protocol buffer的二进制格式的时候(以上文本格式只是为了有一个更可读的展示和编辑方式),大概需要100-200纳秒来解析。采用XML方案,在移除所有空格的前提下,至少需要69bytes数据,并且需要5000=10000纳秒来解析。
同样,操作一个protocol buffer也更容易:

  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;


然而,protocol buffer并不总是比XML更好的方案--例如,protocol buffer不是一个好的方式表达一个基于文本的用标签描述的文档(例如HTML),因为你不能够轻松的表示交叉数据结构。另一方面,XML是人类可读可编辑的,protocol buffer至少在原生格式中无法做到这点。另外XML在某种程度上,是自我表达的格式,protocol buffer数据仅仅在你有.proto定义文件的时候才能明白其意思。


Sounds like the solution for me! How do I get started?
Download the package--这里面包含了完整的生成Java、Python以及C++源代码的编译器,同时还有你在I/O和测试的时候需要的类。编译和安装编译器请参看README里面的指导。
一旦你准备就绪,按以下 步骤生成你需要的语言的版本的protocol buffer。这将引导你完成创建一个使用protocol buffer的简单应用程序。


历史简介
Google为开发有序服务器请求/响应协议( an index server request/response protocol)的时候引入protocol buffer的。在protocol buffer之前,需要用手动处理的方式来编组/解组请求和响应。这导致了一些非常丑陋的代码,例如:

 if (version == 3) {
   ...
 } else if (version > 4) {
   if (version == 5) {
     ...
   }
   ...
 }
 

明确的格式化协议也使得新的协议版本的推出更加复杂,因为开发者要确保原始请求和实际服务器能够处理和明白新的协议的意思。
Protocol buffers就是为了解决这类问题诞生的:
·新的字段能够轻易引入,中转服务器无需检查知道其数据的所有字段就能简单解析数据。
·更加自我表达的格式,并且能够兼容多种语言(C++,Java等)


但是,用户仍然需要手工编写自己的解析代码。
随着系统的演变,它增加了一些其他的特性和用途:
·自动生成的序列化和反序列化的代码避免了需要手工解析。
·为了被短生命周期的RPC(Remote Procedure Call)使用,人们开始使用protocol buffers作为一个方便的自描述格式来持久地存储数据(例如,在Bigtable中)。
·服务器的RPC接口开始宣布使用protocol buffers,用 protocol compiler生成的stub classes,用户可以用actual implementations来override服务器的接口。

Protocol buffers are now Google's lingua franca for data – at time of writing, there are 48,162 different message types defined in the Google code tree across 12,183 .proto files. They're used both in RPC systems and for persistent storage of data in a variety of storage systems.



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值