Protobuffer教程
目录
1.什么是protobuffer?
protobuffer是一种灵活,高效,自动化的机制,用于序列化结构化数据 - 想想XML,但更小,更快,更简单。您可以定义数据的结构化时间,然后可以使用特殊生成的源代码轻松地在各种数据流中使用各种语言编写和读取结构化数据。您甚至可以更新数据结构,而不会破坏根据“旧”格式编译的已部署程序。
2.protobuffer是如何工作的?
您可以通过在.proto文件中定义协议缓冲区消息类型来指定您希望如何构建序列化信息。每个协议缓冲区消息都是一个小的逻辑信息记录,包含一系列名称 - 值对。以下.proto是定义包含有关人员信息的消息的文件的一个非常基本的示例:
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;
}
如您所见,消息格式很简单 - 每种消息类型都有一个或多个唯一编号的字段,每个字段都有一个名称和一个值类型,其中值类型可以是数字(整数或浮点数),布尔值,字符串,字节,甚至(如上例所示)其他协议缓冲区消息类型,允许您分层次地构建数据。您可以指定可选字段,必填字段和重复字段。您可以.proto在Protocol Buffer Language Guide中找到有关编写文件的更多信息。
一旦定义了消息,就可以在.proto文件上运行应用程序语言的协议缓冲区编译器来生成数据访问类。这些为每个字段(如name()和set_name())提供了简单的访问器,以及将整个结构序列化/解析为原始字节的方法 - 例如,如果您选择的语言是C ++,则在上面的示例中运行编译器将生成了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;
您可以在消息格式中添加新字段,而不会破坏向后兼容性; 旧的二进制文件在解析时只是忽略新字段。因此,如果您的通信协议使用协议缓冲区作为其数据格式,则可以扩展协议,而无需担心破坏现有代码。
您将在API参考部分找到有关使用生成的协议缓冲区代码的完整参考,您可以在协议缓冲区编码中找到有关如何编码协议缓冲区消息的更多信息。
3.为什么不使用XML?
对于序列化结构化数据,protobuffer比XML具有许多优点。protobuffer:
- 更简单
- 比小3到10倍
- 快20到100倍
- 不那么暧昧
- 生成更易于以编程方式使用的数据访问类
例如,假设你想要定义一个拥有一个name和email的person。在XML中,您需要:
<person>
<name>John Doe</name>
<email>jdoe@example.com</email>
</person>
而使用相应的protobuffer是:
# Textual representation of a protocol buffer.
# This is *not* the binary format used on the wire.
person {
name: "John Doe"
email: "jdoe@example.com"
}
当此消息被编码为protobuffer二进制格式(上面的文本格式只是用于调试和编辑的方便的人类可读表示)时,它可能长达28个字节并且需要大约100-200纳秒来解析。如果删除空格,XML版本至少为69个字节,并且需要大约5,000-10,000纳秒才能解析。
此外操作protobuffer数据更容易:
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;
如果你是用xml,可能是这个样子:
cout << "Name: "
<< person.getElementsByTagName("name")->item()->innerText()
<< endl;
cout << "E-mail: "
<< person.getElementsByTagName("email")->item()->innerText()
<< endl;
但是,protobuffer并不总是比XML更好的解决方案 - 例如,protobuffer不是使用标记(例如HTML)对基于文本的文档建模的好方法,因为您无法轻松地将结构与文本交错。此外,XML是人类可读的和人类可编辑的; XML在某种程度上也是自我描述的。只有拥有消息定义(.proto文件)时,protobuffer才有意义。
Protobuffer教程的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
- Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境
一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
- Virtual Box配置CentOS7网络(图文教程)
之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...
随机推荐
- 用yum安装的方法部署lamp服务
# yum install -y httpd php php-mysql mariadb mariadb-server# vim /etc/httpd/conf/httpd.conf <If ...
- 【机器学习】梯度、Hessian矩阵、平面方程的法线以及函数导数的含义
想必单独论及" 梯度.Hessian矩阵.平面方程的法线以及函数导数"等四个基本概念的时候,绝大部分人都能够很容易地谈个一二三,基本没有问题. 其实在应用的时候,这几个概念经常被混 ...
- flask类装饰器
from flask import Flask,request,views from functools import wraps app = Flask(__name__) #自定义登录装饰器 de ...
- ssl安全验证
#ssl验证 r=requests.get('https://www.12306.cn',verify=False) print(r.content.decode('utf-8')) 结果:
- 02-Zookeeper介绍及安装
1 Zookeeper介绍 ZooKeeper是为分布式应用所设计的高可用.高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务.分布式应用可以基于它实现更高级的服务,实现诸如同步服务.配置 ...
- 北京望京SOHO-电商墨镜面试题
我去面试,boos 给出了个.动态规划的题目: ‘’‘’‘’ A = "asdf" B = "axazxcv" S = "axasazdxfcv&qu ...
- Django发送邮件和itsdangerous模块的配合使用
项目需求:用户注册页面注册之后,系统会发送一封邮件到用户邮箱,用户点击链接以激活账户,其中链接中的用户信息需要加密处理一下 其中激活自己邮箱的smtp服务的操作就不在加以说明,菜鸟教程上有非常清晰的讲 ...
- JAVA文件类工具
FileUtil package cn.jiangzeyin.util.file; import org.springframework.util.Assert; import java.io.*; ...
- idea 去除重复代码提醒
- cut--修剪小能手
cut命令 cut原理:以每一行位一个处理对象. 参数选项 解释说明 -b 以字节为单位进行分割 -c 以字符为单位进行分割(对切割中文有奇效) -d 自定义分隔符号,默认以tab为分隔符 1:-b ...