欢迎使用协议缓冲器的开发人员指南。 协议缓冲器是一种语言中立、平台中立、通信协议、数据存储和其他领域结构化数据序列化的扩展方法。
本文档主要面向希望在Java、c或Python开发者开发的APP应用程序中使用协议缓冲器的人。 本协议缓冲器的概要介绍将教您如何使用协议缓冲器。 如果您想了解更多关于协议缓冲器的信息,可以访问教程或协议缓冲器编码页面以了解更多信息。
有关API的参考文档,请参阅参考页。 参考文档提供了所有这三种语言的参考,还提供了有关. proto language和style的指南。
什么是 Protocol Buffers
协议缓冲器灵活高效,用于序列化结构化数据。 可以把自动化工具——协议缓冲器想象成XML,但是更小、更快、更简单。可以自己定义结构化数据。 然后,可以使用特定的代码生成工具来非常轻松地读取和写入结构化数据。 这些数据的读取和写入可以使用与一系列数据流不同的计算机程序语言。 也可以在不破坏已部署的程序的情况下更新数据结构。
Protocol Buffers 是如何进行工作的
你需要制定你想如何排序你的数据。 你在proto文件中定义了你的消息结构化数据。每个协议缓冲器消息都是一个小的信息记录逻辑,该消息包含一系列名称、变量匹配序列。
以下是定义了包含珀尔森信息的消息的基本. proto文件。
消息个人
必需字符串名称=1;
必需的int 32标识=2;
可选字符串电子邮件=3;
枚举电话类型{
MOBILE=0;
主页=1;
工作=2;
}
消息电话号码{2}
要求字符串编号=1;
optionalphonetypetype=2[默认=家庭];
}
备用电话号码电话=4;
}
如上所示,这条消息的格式非常简单。 ——每个消息类型都有一个或多个唯一的编号字段,每个字段都包含名称和变量类型。
变量可以是数值(格式或浮点型) numbers (数字)、布尔型)、字符串)、strings (字符串)、本机二进制)以及其他协议缓冲器消息类型,并且可以是分层结构的您的数据
可以将字段指定为“可选字段”(可选字段)、“必需字段”(required fields )、“重复字段”(repeated fields )。 有关. proto的定义,请参见以下协议缓冲器语言指南页。
成功定义消息后,可以使用为所用语言定义的. proto运行协议缓冲器编译器(协议缓冲器编译器)以生成数据访问类。
对于每个字段,数据访问类提供了一种简单的访问方法,如name (或set_name ),以及将本机二进制数据序列化和从本机二进制数据反序列化的方法。
对于上述定义,如果你现在使用c语言,粗心的云编译消息定义,就会得到一个叫做Person的类。 将数据序列化,从序列化的数据(协议缓冲器消息)中重新获取珀尔森的数据。
然后你可以写类似于个人的东西; 的代码。
人员人员;
人物名称(约翰德);
人员设置标识符(1234;
person.set _ email (jdoe @ example.com);
自由输出(我的文件)、IOs :输出| IOs 33603360二进制);
Person .序列化辅助流(输出);
然后,可以读取消息。
足球甲级联赛
m 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 系统和存储系统中存储数据。