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. CAS 单点登录流程

    经验:在网上学东西不要指望一篇文章就能让你明白——我在网上学CAS流程,看了五六篇博文,其中三篇是觉得作者表达能力不行,或者作者自己就没明白怎么回事就出来写东西,看到一半就跳过了,剩下两篇每篇看了两遍 ...

  2. 加密算法使用(一):用CRC32来压缩32uuid字符串

    CRC32相比MD5重复率较高, 不过我们仍然可以使用CRC32然后转长整形的方式将32位的UUID字符串压缩成更短的整形唯一标识. /** * * @Title: getCRC32Value * @ ...

  3. javarebel热部署 (转)

    Java web开发部署效率浅析 在进行java web程序开发过程中,经常遇到这种问题,修改一个java文件(*.java),需要重启web服务器(如tomcat,weblogic等),部署项目.而 ...

  4. python爬虫中文网页cmd打印出错问题解决

    问题描述 用python写爬虫,很多时候我们会先在cmd下先进行尝试. 运行爬虫之后,肯定的,我们想看看爬取的结果. 于是,我们print... 运气好的话,一切顺利.但这样的次数不多,更多地,我们会 ...

  5. 完美隐藏win7文件和文件夹

    有没有一种方法即使使用隐藏模式也不能查看, 没错可以用上帝模式....... 啥是Win7上帝模式?不知道的看看..... <<<<<<<<<&l ...

  6. python数字图像处理(11):图像自动阈值分割

    图像阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素 ...

  7. ios —— UIViewAdditions 布局坐标类库

    方便大家计算视图的高度,宽度,上下左右坐标,简化代码操作,更加直观 下载地址:http://download.csdn.net/detail/humingtao2013/7511657

  8. 微信小程序全选,微信小程序checkbox,微信小程序购物车

    微信小程序,这里实现微信小程序checkbox,有需要此功能的朋友可以参考下. 摘要: 加减商品数量,汇总价格,全选与全不选 设计思路: 一.从网络上传入以下Json数据格式的数组  1.标题titl ...

  9. 江湖恩仇录之PHP程序CPU高占用优化经历分享

    故事起因 本故事根据真实故事书写,如有雷同绝非巧合.在开发过程中难免反复修改程序,面对突然起来的问题难免束手无策,有些人选择自我处理问题,也有人选择交流区域咨询,或许恰巧有人有类似的问题,刚好可以解决 ...

  10. [整理] ES5 词法约定文档树状图

    将ES5 词法说明整理为了树状图,方便查阅,请自行点开小图看大图: