Protocol Buffers 开发者指南
欢迎来到 protocol buffers 的开发者指南。protocol buffers 是一个语言中立,平台中立针对通讯协议,数据存储和其他领域中对结构化数据进行序列化的扩展方法。
本文档主要针对的是 Java,C++ 或 Python 的开发人员希望在开发的应用程序中使用 Protocol Buffers。这个有关 Protocol Buffers 摘要性的介绍将会告诉你如何开始使用 Protocol Buffers。如果你希望更加深入的了解有关 Protocol Buffers 的内容,你可以进入 tutorials 或者 protocol buffer encoding 页面来详细了解。
有关 API 的参考文档,请参考页面:reference documentation 这里提供了所有这 3 种语言的参考,同时也针对 .proto language 和 style 提供相关的指南。
什么是 Protocol Buffers?
Protocol buffers 是对结构化数据序列化的一个灵活,高效,自动化工具 —— 你可以将 Protocol buffers 想象成 XML,但是体积更小,更快也更加简单。
你可以自己定义你的结构化数据,然后你可以使用特定的代码生成工具来非常容易对你的结构化数据进行读取和写入。这些数据的读取和写入可以是一系列的数据流和使用不同的计算机程序语言。你甚至可以在不对已经部署的程序进行破坏的情况下更新你的数据结构。
Protocol Buffers 是如何进行工作的
你需要制定你希望如何将你的数据进行序列化。你是通过 proto 文件来定义你的消息结构化数据的。
每一 protocol buffer message 是一个小的信息记录逻辑,这个消息中包含有一系列的名字,变量对照序列。下面是一些基本的.proto 文件,这些文件中定义了一个消息,这个消息包含有一个 person 信息:
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;} | 
通过上面你可以看到这个消息的格式非常简单—— 每一个消息类型都有一个或者多个唯一进行编号的字段,每一个字段包含有一个名字和变量类型。
变量可以为数字(整形或者浮点型)(numbers),布尔类型(booleans),字符串(strings),原生二进制(raw bytes)甚至其他的 protocol buffer 消息类型,能够允许你分级的结构化你的数据。
你可以将字段指定为可选字段(optional fields),必须字段(required fields)和重复字段(repeated fields)。你可以从下面的 Protocol Buffer Language Guide 页面中找到更多有关 .proto 的定义。
一旦你成功定义了你的消息,你可以针对你使用的语言使用你定义的 .proto 来运行 protocol buffer 编译器(protocol buffer compiler)来生成数据访问类。
针对每一个字段,在数据访问类中提供了简单的访问方法(例如 name() 和 set_name())和序列化到原生 2 进制数据和从原生 2 进制数据反序列化的方法。
针对上面的定义,如果你现在使用的是  C++ 语言的话,当你把消息定义进行编译后,你将会得到一个称为 Person 的类。 你可以使用这个类在你的应用程序中进行填充数据,对数据进行序列化和从序列化的数据中(protocol buffer 消息)重新获得 Person 数据。
然后你可以写一些类似 Person 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; | 
你可以向你的消息中添加新的字段而不会损坏老的消息。这是因为在老的消息处理中,针对新的字段是完全忽略掉的。因此,如果你在你的通讯协议中使用 protocol buffers 为数据结构的话,你可以对你的协议和消息进行扩展而不需要担心老的代码没有办法编译通过,或者损坏老的代码。
你可以访问 API Reference section 页面中的内容来了解完整 protocol buffer 代码的生成和使用。
你也可以在 Protocol Buffer Encoding 页面中了解更多protocol buffer 消息是如何进行编码的。
为什么不使用 XML
针对 XML 来说 Protocol Buffers 具有更多的优势来对序列化结构数据。
- 更加简单
 - 小于 XML 3 到 10 倍
 - 快于 XML 20 到 100 倍
 - 松耦合
 - 使用程序工具来创建数据访问类,使数访问类更加简单
 
假设,你需要讲 person 这个数据进行定义,在 XML 你需要使用:
<person>  <name>John Doe</name>  <email>jdoe@example.com</email></person> | 
来进行定义。
在 Protocol Buffers 中针对上面的消息文本化(text format)后显示为:
# 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 二进制格式(binary format)上面的文字可能小于 28 bytes,并且可能需要 100-200 纳秒(nanoseconds)来进行处理。
我们将上面转换为可以人为读取的目的主要是为进行调试和编辑。
如果你使用 XML 的话,上面的信息至少需要 69 bytes (你需要删除所有的空格),同时你需要 5,000-10,000 纳秒(nanoseconds)来进行处理。
同时,对 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 buffers 并不是任何时候都会比 XML 好。例如,针对基于文本的标记语言(例如,XML),protocol buffers 就不是一个很好的选项,因为你不能使用 protocol buffer 更好的在文档中进行交换。更主要的是 HTML 是人类可以阅读和编辑的。protocol buffer 也不是不可以人为的读取,但是针对原生的 protocol buffer 格式是没有办法人为进行读取和编辑的。
XML 与 HTML 一样,在某种程度上是一种自我描述数据。protocol buffer 只针对你在 .proto 文件中描述的内容进行表达。
看起来像一个解决方案,我应该如何开始呢?
Download the package – 这包中含有针对 Java, Python, 和 C++ protocol buffer 编译器源代码,和你需要进行 I/O 和测试的类。希望对你的编译器进行编译和构建,请参考代码中的 README 文件。
一旦你完成了所有的设置,请参考 tutorial 页面中的内容来选择你需要的语言——这个能够帮助你使用 protocol buffer 创建一个简单的应用程序。
介绍 proto3
在我们最新的 version 3 发行版 中推出了新的语言版本 —— Protocol Buffers language version 3(另称 proto3),在这个版本中针对我们已经存在的语言版本(proto2)使用了一些新的特性。
Proto3 简化了 protocol buffer 语言,使其更加容易使用并且能够支持更多的语言:我们当前发行的 proto3 能够让你创建 Java, C++, Python, Java Lite, Ruby, JavaScript, Objective-C, and C#。
另外你也可以通过使用 Go protoc 插件来用 proto3 创建 Go 代码,这个插件你可以到 golang/protobuf Github 中下载到。更多的语言还在逐步进行支持中。
请注意,这 2 个版本的 API 并不是完全兼容的。为了照顾还在使用老版本的用户,我们将会在新的 protocol buffers 发行中同时支持老的版本。
你可以在下面的发行日志(release notes)查看 2 个版本的主要不同。有关 proto3 的句法,请参考 Proto3 Language Guide 中的内容,针对 proto3 的完整文档还没有编写完成,将会随后推出。
看起来 proto2 和 proto3 可能会产生一些混淆,这是因为原始的开源 protocol buffers 实际上是 Google 内部语言的第二个版本,同时我们的开源版本也是从 v2.0.0 开始的。简单来说就是 proto 最开始的版本是 Google 内部使用的,在 proto 第二个版本的时候,Google 决定进行开源了,所以开源的 proto 是从 proto2 开始的。
一个简短的历史
Protocol buffers 最开始是在 Google 内部进行开发的,用于处理在索引服务器上请求/响应(request/response)的协议。
在 Protocol buffers 之前,针对请求和响应,使用的是 marshalling/unmarshalling,这个能够支持一系列的协议。但是结果看起来却是非常的难看,例如:
if (version == 3) {  ...} else if (version > 4) {  if (version == 5) {    ...  }  ...} | 
明确格式化的的协议也使新版本的协议更加难以推出,这是因为开发者必须能够了解老协议在服务器之间是如何进行处理的,同时也需要了解新的协议。只有对新老协议都有所了解后才能逐步使用新的协议替换老的协议。
Protocol buffers 被用来设计解决上面的很多问题:
- 新的字段比较能够容易的进行定义,中级服务器不需要对数据进行检查,直接对数据进行处理,同时也可以直接传输数据而不需要了解数据是如何进行定义的。
 - 格式使用自描述,能够更加容易支持更多的语言(C++,Java 等)。
 
但是,用户还是需要手动书写他们自己的处理diam。
作为系统的进化来说,它获得了许多其他的特性和用途:
- 自动生成序列化和反序列化代码而避免手动书写这些代码。
 - 除了开始使用短期RPC(远程过程调用)请求,人们开始使用 protocol buffers 作为高效的自描述结构化数据格式(主要针对数据短期存在,例如在 Bigtable)。
 - 服务器RPC接口开始被声明为协议文件的一部分,协议编译器生成根类,用户可以通过服务器接口的实现和重载它们。
 
Protocol buffers 在 Google 中成为针对数据的通用语言—— 随着时间的流逝,在 Google 内部已经有超过 348,952 .proto 文件被定义。这些被用在 RPC 系统和存储系统中存储数据。
https://www.cwiki.us/display/ProtocolBuffers/Developer+Guide
Protocol Buffers 开发者指南的更多相关文章
- Protocol Buffers(Protobuf)开发者指南---概览
		
Protocol Buffers(Protobuf)开发者指南---概览 欢迎来到protocol buffers的开发者指南文档,protocol buffers是一个与编程语言无关‘.系统平台无关 ...
 - Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南
		
Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南 约定:为方便书写,ProtocolBuffers在下文中将已Protobuf代替. 本指南将向您描述如何使用 ...
 - Protocol Buffers官方文档(proto3语言指南)
		
本文是对官方文档的翻译,大部分内容都是引用其他一些作者的优质翻译使文章内容更加通俗易懂(自己是直译,读起来有点绕口难理解,本人英文水平有限),参考的文章链接在文章末尾 这篇指南描述如何使用protoc ...
 - ProtoBuf3语法指南(Protocol Buffers)_下
		
0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.A ...
 - ProtoBuf3语法指南(Protocol Buffers)_上
		
0.说明 ProtoBuf3语法指南, 又称为proto3, 是谷歌的Protocol Buffers第3个版本. 本文基于官方英文版本翻译, 加上了自己的理解少量修改, 一共分为上下两部分. 1.序 ...
 - Protocol Buffers官方文档(开发指南)
		
本文是对官方文档的翻译,然后截取了一篇非常优秀的文章片段来帮助理解,本人英文水平有限,基本都是直译,如果有不理解的地方请参考英文官方文档,参考的文章链接在文章末尾 protocol buffers简介 ...
 - protocol buffer开发指南(官方)
		
欢迎来到protocol buffer的开发者指南文档,一种语言无关.平台无关.扩展性好的用于通信协议.数据存储的结构化数据序列化方法. 本文档是面向计划将protocol buffer使用的到自己的 ...
 - GOOGLE PROTOBUF开发者指南
		
原文地址:http://www.cppblog.com/liquidx/archive/2009/06/23/88366.html 译者: gashero 目录 1 概览 1.1 什么是pro ...
 - 使用 Protocol Buffers 代替 JSON 的五个原因
		
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
 
随机推荐
- 【Linux-驱动】将cdev加入到系统中去---cdev_add
			
在我们已经完成了对cdev结构体的初始化之后,我们需要将这个cdev结构体加入到系统中去,使用函数 cdev_add: /** * cdev_add() 讲一个字符设备加入到系统中去 * @p: 字符 ...
 - sql server之批量数据导入
			
实际应用场景中,有时会需要把一批数据导入数据库.这批数据可能来源于另一个数据源.比较常规的做法是先读取到dataset,然后跑一个循环,每一行拼一句insert into语句,执行之.用过的人会知道, ...
 - Java基础(六)
			
面向对象 概述 生活举例 代码体验 类与对象的关系 类的定义 根据类创建对象 对象的基本使用 练习:手机类与对象 内存图:一个对象 内存图:两个对象 内存图:同一个对象 局部变量与成员变量的区别 pr ...
 - 设计模式在 Spring 框架中的良好应用
			
在开始正文之前,请你先思考几个问题: 你项目中有使用哪些 GOF 设计模式 说一说 GOF 23 种设计模式的设计理念 说说 Spring 框架中如何实现设计模式 假设我是面试官问起了你这些面试题,你 ...
 - Java第七周课堂示例总结
			
一.super();调用基类构造方法 代码: class Grandparent{ public Grandparent(){ System.out.println("GrandParent ...
 - sql server  isnull函数
			
isnull函数 --ISNULL() 函数用于规定如何处理 NULL 值 语法:SELECT ISNULL(check_expression, replacement_value) --check_ ...
 - 特产网站自适应CSS
			
下面是一个特产网站自适应CSS,这个特产自适应CSS通过屏幕宽度大小来进行适应的,而不是根据UA来判断,就加快了判断的速度,所以速度很快 中国特产站排名还是很好的,特别是手机端 li { list-s ...
 - 转载: Ubuntu 在命令下,安装中文环境的方法。
			
转载: https://blog.csdn.net/zhangchao19890805/article/details/52743380 安装英文版ubuntu,在打开含有中文字符文件时会乱码,有需要 ...
 - Exited too quickly (process log may have details)-配置问题
			
在配置supervisor的时候,提示Exited too quickly (process log may have details),这个时候一脸懵逼,啥回事,执行太快了???
 - Linux: df du
			
df :列出文件系统的整体磁盘使用量 du :评估文件系统的磁盘使用量(常用在推估目录所占容量) 1 df :[-ahikHTm] 目录或文件名 选项或参数: -a: 列出所有的文件系统,包括系统 ...