Protocol Buffers(Protobuf)开发者指南---概览

欢迎来到protocol buffers的开发者指南文档,protocol buffers是一个与编程语言无关‘、系统平台无关、可扩展的结构化数据序列化/反序列化工具,适用于通讯协议,数据存储等场合。

ps:为了方便拼写,下文的protobuf就是指protocol buffers。

本文档的面向读者是:希望使用protobuf的 Java、C++、Python的开发者。此概览将向您介绍如何开始使用protobuf,然后您可以跟着示例进行学习,或者深入了解protobuf的编码方式。API参考文档同样提供了此三种语言的版本,而且为了更好的编写.proto文件提供了语言指导、风格指导文档。

-------------------------------------------------------------------------------------小小的分割线----------------------------------------------------------------------------------------------------------

protobuf是什么?

protobuf 是一个灵活、高效,使用自动化机制的结构化数据序列工具,类似于XML,但比XML更小巧、更快、而且也更简单。只需要定义一次数据结构,你就可以使用代码生成器生成各种编程语言和各种流式文件的结构化读取和写入。甚至可以在无需重新编译部署新程序的情况下更新新的结构化数据。

他们是如何工作的?

你需要在protobuf信息文件内(.proto)指定你需要序列化的信息是什么样的结构。每个protubuf信息是一小段逻辑记录,包含一系列的“键--值”组合。这有一个定义了个人信息的protobuf信息文件例子!

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消息类型(就像上面的例子一样PhoneNubmer的PhoneType类型是自定的protobuf消息类型),允许您使用多层次的结构体,你可以指定optional(可选)、required(必须)、repeated(重复),需要更多的关于.proto信息文件的编写帮助请查看protobuf语言指南

一旦你定义了自己的消息格式(message),你就可以运行protobuf编译器,将你的 .proto 文件编译成特定语言的类。这些类提供了简单的方法访问每个字段(类似query() 和 set_query() ),就像访问类的方法一样将结构序列化或反序列化。例如你可以选择C++语言,运行编译如上的协议文件生成叫做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;

你可以在不影响向后兼容的情况下随意给数据结构增加字段,旧有的数据会忽略新的字段。所以如果使用protobuf作为通信协议,你可以无须担心破坏现有代码的情况下扩展协议。

你可以在此找到完整的API参考 API Reference section, 关于Protobuf如何编码可以在此找到完整的文档Protocol Buffer Encoding.

为何不使用XML?

protobuf拥有比XML更多高级的序列化特点:

  • 更简单
  • 小3-10倍
  • 快20-100倍
  • 更少的歧义
  • 可以方便的生成数据存取类,易于使用
例如,让我们看看如何在XML中建模Person的name和email字段:

  1. <person>
  2. <name>John Doe</name>
  3. <email>jdoe@example.com</email>
  4. </person>
  1. <person>
  2. <name>John Doe</name>
  3. <email>jdoe@example.com</email>
  4. </person>

对应的ProtocolBuffer报文则如下:此为protobuf的文本表示
这不是正常时使用的二进制数据

  1. person {
  2. name: "John Doe"
  3. email: "jdoe@example.com"
  4. }
  1. person {
  2. name: "John Doe"
  3. email: "jdoe@example.com"
  4. }

当这个报文编码到protobuf的二进制格式时(上面的文本仅用于调试和编辑),它只需要28字节和100-200ns的解析时间。而XML的版本需要69字节(除去空白)和 5000-10000ns的解析时间。

当然,操作Protobuf也很简单:

  1. cout << "Name: " << person.name() << endl;
  2. cout << "E-mail: " << person.email() << endl;
  1. cout << "Name: " << person.name() << endl;
  2. cout << "E-mail: " << person.email() << endl;

而XML的你需要:

  1. cout << "Name: "
  2. << person.getElementsByTagName("name")->item(0)->innerText()
  3. << endl;
  4. cout << "E-mail: "
  5. << person.getElementsByTagName("email")->item(0)->innerText()
  6. << end;
  1. cout << "Name: "
  2. << person.getElementsByTagName("name")->item(0)->innerText()
  3. << endl;
  4. cout << "E-mail: "
  5. << person.getElementsByTagName("email")->item(0)->innerText()
  6. << end;

当然,Protobuf并不是在任何时候都比XML更合适,例如Protobuf无法对一个基于标记文本的文档建模,因为你根本没法方便的在文本中插入结构。另外,XML是便于人类阅读和编辑的,而Protobuf则不是。还有XML是自解释的,而Protobuf仅在你拥有报文格式定义的 .proto 文件时才有意义。

 
 
感觉这个解决方案很不错,非常适合我,应该如何开始呢?
 
点击下载protobuf包 – 这包含了 Java、Python、C++的protobuf编译器源码,如何 生成你需要的IO类。构建和安装protobuf编译器,请查阅README的文档。
一旦都准备好了的话,尝试跟随你选择的语言的指导例程,它将一步步的指导你如何使用protobuf构建应用程序!
 
关于Protobuf的一点历史
protobuf最初是在Google开发的,用以解决索引服务器的请求、响应协议。在使用ProtocolBuffer之前,有一种格式用以处理请求和响应数据的编码和解码,并且支持多种版本的协议。而这最终导致了丑陋的代码,例如:
 if (version == 3) {
   ...
 } else if (version > 4) {
   if (version == 5) {
     ...
   }
   ...
 }

通信协议因此变得越来越复杂,因为开发者必须确保,发出请求的人和接受请求的人必须同时兼容,并且在一方开始使用新协议时,另外一方也要可以接受。

Protobuf设计用于解决这一类问题:

  • 很方便引入新字段,而中间服务器可以忽略这些字段,直接传递过去而无需理解所有的字段。
  • 格式可以自描述,并且可以在多种语言中使用(C++、Java等)

然而用户仍然需要手写解析代码。

随着系统的演化,他需要一些其他的功能:

  • 自动生成编码和解码代码,而无需自己编写解析器。
  • 除了用于简短的RPC(Remote Procedure Call)请求,人们使用protobuf来做数据存储格式(例如BitTable)。
  • RPC服务器接口可以作为 .proto 文件来描述,而通过protobuf的编译器生成存取(stub)类供用户实现服务器接口。

protobuf现在已经是Google的混合语言数据标准了,现在已经正在使用的有超过48,162种报文格式定义和超过 12,183个 .proto 文件。他们用于RPC系统和持续数据存储系统。

原文地址:https://developers.google.com/protocol-buffers/docs/overview

参考翻译自:小狼.exe的博客:http://blog.163.com/jiang_tao_2010/blog/static/12112689020114305013458/

Protocol Buffers(Protobuf)开发者指南---概览的更多相关文章

  1. Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南

    Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南 约定:为方便书写,ProtocolBuffers在下文中将已Protobuf代替. 本指南将向您描述如何使用 ...

  2. GOOGLE PROTOBUF开发者指南

    原文地址:http://www.cppblog.com/liquidx/archive/2009/06/23/88366.html 译者: gashero 目录 1   概览 1.1   什么是pro ...

  3. ProtoBuf开发者指南

    目录 1   概览 1.1   什么是protocol buffer 1.2   他们如何工作 1.3   为什么不用XML? 1.4   听起来像是为我的解决方案,如何开始? 1.5   一点历史 ...

  4. Protocol buffers编写风格指南

    原文链接:https://developers.google.com/protocol-buffers/docs/style Style Guide 本文说明了.proto文件的编写风格指南.遵循这些 ...

  5. Protocol Buffers 开发者指南

    欢迎来到 protocol buffers 的开发者指南.protocol buffers 是一个语言中立,平台中立针对通讯协议,数据存储和其他领域中对结构化数据进行序列化的扩展方法. 本文档主要针对 ...

  6. Protobuf语言指南(转)

    Protobuf语言指南 l  定义一个消息(message)类型 l  标量值类型 l  Optional 的字段及默认值 l  枚举 l  使用其他消息类型 l  嵌套类型 l  更新一个消息类型 ...

  7. Protobuf语言指南

    Protobuf语言指南 l  定义一个消息(message)类型 l  标量值类型 l  Optional 的字段及默认值 l  枚举 l  使用其他消息类型 l  嵌套类型 l  更新一个消息类型 ...

  8. Protocol Buffers官方文档(proto3语言指南)

    本文是对官方文档的翻译,大部分内容都是引用其他一些作者的优质翻译使文章内容更加通俗易懂(自己是直译,读起来有点绕口难理解,本人英文水平有限),参考的文章链接在文章末尾 这篇指南描述如何使用protoc ...

  9. ProtoBuf3语法指南(Protocol Buffers)_下

    0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.A ...

随机推荐

  1. 【原创】有关Silverlight中“DataGrid中级联动态绑定父/子ComboBox ”的示例。

    尝试了很多种方案,由于Datagrid动态生成的每行父子comboBox的Name的不确定性,给父ComboBox绑定事件中获取 子ComboBox很难根据Name获取到. 花了不少时间和公司同事商讨 ...

  2. Delphi7的HtmlParser使用方法

    uses HtmlParser procedure TForm4.Button1Click(Sender: TObject); var FNodes:IHtmlElement; aString:str ...

  3. Use CLR Profiler

    Use CLR Profiler 第一次翻译对我而言比较长的E文,有很多不足之处,请见谅.(个人的习惯GC又做了名词又做了名词) 原文:http://msdn.microsoft.com/en-us/ ...

  4. C#字符格式化占位符

    using System; using System.Diagnostics; using System.Text; using System.Collections; using System.Co ...

  5. Android View事件机制 21问21答

    原文: http://www.cnblogs.com/punkisnotdead/p/5179115.html#3358859 1.View的坐标参数 主要有哪些?分别有什么注意的要点? 答:Left ...

  6. linux实践——简单程序破解

    一.运行login可执行程序,屏幕显示需要输入密码,随便输入一串字符,结果是Drop dead! 二.objdump -d login,对login进行反汇编,找到main函数,找到含有scanf的那 ...

  7. Expectation maximization - EM算法学习总结

    原创博客,转载请注明出处 Leavingseason http://www.cnblogs.com/sylvanas2012/p/5053798.html EM框架是一种求解最大似然概率估计的方法.往 ...

  8. openssl知识点总结

    openssl知识点总结 实践总结见之前博客:http://www.cnblogs.com/Jclemo/p/6091201.html 简介 openssl是一个功能丰富且自包含的开源安全工具箱.它提 ...

  9. 用nginx的反向代理机制解决前端跨域问题

    什么是跨域以及产生原因 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制 ...

  10. BinaryWrite方法输出验证码

    在创建网站中验证码是不可或缺的.可以利用BinaryWrite输出二进制图像的方法输出验证码. 在开发图形验证码时,首先生成验证码,然后绘制成图像,最后通过该方法输出到页面中.所以熟练地掌握该方法可以 ...