protobuf详解
1 protobuf 简介
protobuf
(protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域和语言无关、平台无关、可扩展的序列化结构数据格式。
我们说的 protobuf
通常包括下面三点:
一种二进制数据交换格式。可以将 C++ 中定义的存储类的内容与二进制序列串相互转换,主要用于数据传输或保存
定义了一种源文件,扩展名为
.proto
(类比.cpp
文件),使用这种源文件,可以定义存储类的内容protobuf有自己的编译器
protoc
,可以将.proto
编译成.cc
文件,使之成为一个可以在 C++ 工程中直接使用的类
序列化:将数据结构或对象转换成二进制串的过程。
反序列化:将在序列化过程中所产生的二进制串转换成数据结构或对象的过程。
2 定义proto文件
2.1 message
介绍
message
:protobuf
中定义一个消息类型是通过关键字message
字段指定的,这个关键字类似于C++/Java中的class关键字。使用 protobuf 编译器将proto
编译成C++代码之后,每个message
都会生成一个名字与之对应的C++类,该类公开继承自google::protobuf::Message
。
2.2 message
消息定义
创建tutorial.person.proto
文件,文件内容如下:
// FileName: tutorial.person.proto // 通常文件名建议命名格式为 包名.消息名.proto
// 表示正在使用proto2命令 syntax = "proto2"; //包声明,tutorial 也可以声明为二级类型。例如a.b,表示a类别下b子类别 package tutorial; //编译器将生成一个名为person的类 //类的字段信息包括姓名name,编号id,邮箱email,以及电话号码phones message Person { required string name = 1; // (位置1)required int32 id = 2; optional string email = 3; // (位置2)enum PhoneType { //电话类型枚举值 MOBILE = 0; //手机号 HOME = 1; //家庭联系电话WORK = 2; //工作联系电话} //电话号码phone消息体//组成包括号码number、电话类型 typemessage PhoneNumber {required string number = 1; optional PhoneType type = 2 [default = HOME]; // (位置3)} repeated PhoneNumber phones = 4; // (位置4) } // 通讯录消息体,包括一个Person类的people message AddressBook { repeated Person people = 1; }
2.3 模块说明
2.3.1 包声明
proto
文件以package
声明开头,这有助于防止不同项目之间命名冲突。在C++中,以package
声明的文件内容生成的类将放在与包名匹配的namespace
中,上面的.proto
文件中所有的声明都属于tutorial
。
2.3.2 字段规则
required
:消息体中必填字段,不设置会导致编解码异常。(例如位置1)optional
: 消息体中可选字段,可通过default关键字设置默认值。(例如位置2)repeated
: 消息体中可重复字段,重复的值的顺序会被保留(例如位置3)。其中,proto3默认使用packed方式存储,这样编码方式比较节省内存。
2.3.3 标识号
标识号
:在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0,2^29-1]范围内的一个整数。以Person为例,name=1,id=2, email=3, phones=4 中的1-4就是标识号。
2.3.4 数据定义
许多标准的简单数据类型都可以用作message
字段类型,包括bool
,int32
,float
,double
和string
。
还可以使用其他message
类型作为字段类型在消息体中添加更多结构。在上面的示例中,Person
包含PhoneNumber message
, 而AddressBook
包含Person message
。
甚至可以定义嵌套在其他message
中的message
类型。例如,上面的PhoneNumber
定义在Person
中。
2.3.5 message自带方法
用message
关键字声明的的消息体,允许你检查、操作、读、或写整个消息,包括解析二进制字符串,以及序列化二进制字符串。除此之外,也定义了下列方法:
Person:缺省的构造函数。~Person():缺省的析构函数。Person(const Person& other):拷贝构造函数。Person& operator=(const Person& other): 赋值 (Assignment )操作符。const UnknownFieldSet& unknown_fields() const:
返回当解析信息时遇到的未知字段的集合。UnknownFieldSet* mutable_unknown_fields():
返回当前解析信息时遇到的未知字段的集合的一个mutable指针。
3 编译proto文件
可以执行以下protoc
命令对.proto
文件进行编译,生成对应的c文件。Linux系统通过 protoc -help
查看protoc
命令的使用详解。
protoc -I=$SRC_DIR --cpp_out=$DST_DIR xxx.proto
$SRC_DIR
所在的源目录
--cpp_out
生成C++代码
$DST_DIR
生成代码的目标目录
xxx.proto
:要针对哪个proto
文件生成接口,在这里对应tutorial.person.proto
编译完成后,将生成2个文件 tutorial.pb.h
和tutorial.pb.c
其中tutorial
表示包名,pb是protobuf
的缩写。
此外,protocol buffer
编译器为.proto
文件中定义的消息的每个字段生成一套存取器方法:
对于 message Person
中的 required int32 id = 2
,编译器将生成下列存取器方法:
bool has_id() const
: 用于判断字段id
是否存在。如果字段被设置,返回true。
int32 id() const
: 返回字段id
的当前值,如果字段没有被设置,返回缺省值。
void set_id(int32 value)
: 设置字段id
的值。调用此方法后,has_id()
将返回true
以及id()
将返回value
。
void clear_id()
:清除字段的值。调用此方法后,has_id()
将返回false
以及id()
将返回缺省值。
当然,对于其他类型的字段,编译器也会生成不同的存取方法,这里就不一一列举了。
4 使用message
//获取person实例:
tutorial::AddressBook addressBook;
Person *person =
addressBook.add_people(); //写入一个message:
person->set_id(id);
getline(cin,*person->mutable_name());//读取一个message:
person.id();
person.name();
person.email();
扩展一个message:
你不得更改任何现有字段的字段编号
你可以删除
optional
或repeated
属性的字段你可以添加新的
optional
或repeated
字段,但必须使用新的标记
5 protobuf的优点
性能方面
序列化后,数据大小可缩小3倍
序列化速度快
传输速度快
使用方面
使用简单:
proto
编译器自动进行序列化和反序列化维护成本低:多平台只需要维护一套对象协议文件,即
.proto
文件可扩展性好:不必破坏旧的数据格式,就能对数据结构进行更新
加密性好:http传输内容抓包只能抓到字节数据
使用范围
跨平台、跨语言、可扩展性强
6 总结
C++ protocol buffers
已经做了极大优化,当然它的用途不仅仅是简单的访问器和序列化,如果运用好自己的想象力,可以将protobuf
应用于更广泛的问题中。
protobuf详解相关推荐
- ProtoBuf - 详解
之前在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML,而在最近的开发中接触到了 Google 的 ProtoBuf. 在查阅相关资料学习 ProtoBuf 以及研读其源码之后 ...
- ProtoBuf详解(一)概念和语法
关于ProtoBuf ProtoBuf 是谷歌开源的一套与语言无关,平台无关,可扩展性强,兼容性好并且效率很高的数据序列化方法,非常适合用于做二进制数据的通信协议和数据存储.这里可以访问官方文档. 很 ...
- Protobuf 详解
简介 Protobuf全称是Google Protocol Buffer,是一种高效轻便的结构化数据存储方式,可用于(数据)通信协议.数据存储等. 也可以理解为结构化数据的序列化方法,可简单类比为XM ...
- 【C++】Google Protocol Buffer(protobuf)详解(二)
代码走读:caffe中protobuf的详细使用过程 [一]proto文件,以caffe.proto中BlobShape为例 syntax = "proto2"; //指明prot ...
- ProtoBuf格式详解
"介绍protobuf编码格式." protobuf是一种数据交换格式,又称PB编码,由Google开源,类似于Json.XML,但其内部是纯二进制格式,比Json,XML等格式要 ...
- php把proto解析为文档,Protobuf 文件生成工具 Prototool 命令详解
Protobuf 文件生成工具 Prototool 命令详解 简介 Prototool 是 Protobuf 文件的生成工具, 目前支持go, php, java, c#, object c 五种语言 ...
- protobuf2和3同时安装_在 Ubuntu 上安装 Protobuf 3 的教程详解
什么时候需要安装 如果使用 protoc 命令,遇到 Protoc not found,表示未安装.或者,执行时出现错误:This parser only recognizes "proto ...
- js_long.php,protobuf.js 与 Long.js的使用详解
这次给大家带来protobuf.js 与 Long.js的使用详解,是急用protobuf.js 与 Long.js的注意事项有哪些,下面就是实战案例,一起来看一下. protobuf.js的结构和w ...
- protobuf前后端解析_前端后台以及游戏中使用google-protobuf详解
前端后台以及游戏中使用google-protobuf详解 [TOC] 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更小 ...
最新文章
- python爬虫入门代码-如何开始写你的第一个爬虫脚本——简单爬虫入门!
- CSLA .NET 3.6支持Silverlight 2
- c语言四字节转浮点数_C语言浮点书于字节互相转换
- window.open参数完全手册
- 幽灵交易策略_幽灵交易者策略(附源代码)
- Markdown 使用指南
- 小米开源文件管理器MiCodeFileExplorer-源码研究(1)-2个模型Model
- 各位有没有遇到过这样的问题?
- 手机处理器排名2019_手机CPU天梯图2020年3月最新版 你的手机处理器排名高吗?...
- 反三角函数在线计算机,反三角函数(反正弦,反余弦,反正切,反余切,反正割,反余割)在线计算器_三贝计算网_23bei.com...
- fcntl实现对文件加锁功能
- 解决sns加载数据load_dataset()报错问题
- 网络存储学习之网络存储技术的发展现状及趋势
- kuwo.php采集,PHP获取酷我音乐MP3外链
- [codevs1746][NOI2002] 贪吃的九头龙 树形DP
- 使用vue-video-player实现直播
- 辐射避难所买了东西显示服务器异常,辐射避难所有哪些BUG 现存BUG说明及解决方法盘点...
- 导航栏调透明度HTML,导航栏透明度问题
- 住院病人主要由护士护理,这不仅需要大量的护士,而且不能随时观察危重病病情,会延误抢救时机以计算机为中心的患者监护系统,写出系统的可行性。并可以系统印出某个指定病人的病情报告。...
- 手环服务器维修,智能手环解决方案
热门文章
- 财审通做最好的审计软件,审计软件,审计系统,审计专家,审计大师等
- 基于深度学习的目标检测DET - SSD
- pix2pix学习系列(1):预训练模型测试pix2pix
- 【华为 OD】九宫格_全队列
- redis安装make报致命错误:jemalloc/jemalloc.h:没有那个文件或目录
- JVM系列(垃圾回收三)_垃圾收集器
- 11.java设计模式(读书笔记)享元模式
- 四种软件商业模式的分析
- 校园导航系统的设计与实现
- 腾讯2021年营收依然稳居互联网大厂前列,是真的到了“大而不能倒”的程度吗?