Google Protocol Buffers介绍
简要介绍和总结protobuf的一些关键点,从我之前做的ppt里摘录而成,希望能节省protobuf初学者的入门时间。这是一个简单的Demo。
Protobuf 简介
Protobuf全称Google Protocol Buffers
- http://code.google.com/p/protobuf
- 结构化数据存储格式(xml, json)
- 用于通信协议、数据存储等
- 高效的序列化和反序列化
- 语言无关、平台无关、扩展性好
- 官方支持C++, Java, Python三种语言
.proto文件
定义和使用
消息定义文件user_def.proto
package user;
message UserInfo {
required int64 id = ;
optional string name = ;
repeated bytes nick_name = ;
}
编译.proto,生成解析器代码
protoc --cpp_out . user.proto // user_def.pb.h user_def.pb.cc
protoc --java_out . user.proto // user/UserInfo.java
字段ID
optional string name = 2;
- 唯一性
- 序列化后,1~15占一个字节,16~2047占两个字节
字段类型
https://developers.google.com/protocol-buffers/docs/proto#scalar
string vs. bytes
.proto类型 c++类型 java类型 说明 string std::string String 必须是UTF-8或ASCII文本 bytes std::string ByteString 任意的字节序列
编写建议
- 常用消息字段(尤其是repeated字段)的ID尽量分配在1~15之间。
- 尽可能多的(全部)使用optional字段。
- 命名方式
- .proto文件名用underscore_speparated_names。
- 消息名用CamelCaseNames。
- 字段名用underscore_separated_names。
兼容性建议
- 不能修改字段的ID。
- 不能增删任何required字段。
- https://developers.google.com/protocol-buffers/docs/proto#updating
序列化后的protobuf消息
- 一序列的键值对,键是消息字段的ID。
- 已知消息字段(.proto文件定义)按其ID顺序排列。
- 未知消息字段:
- c++和java: 排在已知字段之后且顺序不定。
- python: 不保留未知字段。
- 不包含未赋值的optional消息字段。
- 使用little-endian字节序存储。
反射
反射是protobuf的一个重要特性,涉及到的类主要有:
根据名称创建消息
以下是一个根据消息名(包含package name)创建protobuf消息的C++函数,需要注意的是返回的消息必须在用完后delete掉。
Message* createMessage(const string &typeName) {
Message *message = NULL;
// 查找message的descriptor
const Descriptor *descriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(typeName);
if (descriptor) {
// 创建default message(prototype)
const Message *prototype = MessageFactory::generated_factory()->GetPrototype(descriptor);
if (NULL != prototype) {
// 创建一个可修改的message
message = prototype->New();
}
}
return message;
}
修改消息
根据消息的字段名称修改其值。以上面的user.UserInfo为例,下面将一个新的UserInfo消息的其id字段设为100。
int main() {
// 使用上面的函数创建一个新的UserInfo message
Message *msg = createMessage("user.UserInfo");
if (NULL == msg) {
// 创建失败,可能是消息名错误,也可能是编译后message解析器
// 没有链接到主程序中。
return -;
}
// 获取message的descriptor
const Descriptor* descriptor = msg->GetDescriptor();
// 获取message的反射接口,可用于获取和修改字段的值
const Reflection* reflection = msg->GetReflection();
// 根据字段名查找message的字段descriptor
const FieldDescriptor* idField = descriptor->FindFieldByName("id");
// 将id设置为100
if (NULL != idField) {
reflection->SetInt64(msg, idField, );
}
// ... 其他操作
// 最后删除message
delete msg;
return ;
}
从字符串或流中读取消息
用createMessage创建一个空的消息后,最常见的使用场景是使用Message的ParseFromString或ParseFromIstream方法从字符串或流中读取一个序列化后的message。
Message *msg = createMessage("user.UserInfo");
if (NULL != msg) {
if (!msg->ParseFromString("... serialized message string ... ")) {
// 解析失败
...
}
}
Protobuf优势
- 扩展性好
- 前后兼容
- 引入(import)已定义的消息
- 嵌套消息
- 高效 https://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
- 适合处理大量小数据(单个Message不超过1M)
Protobuf劣势
- 没有内置的Set, Map等容器类型。
- 不适合处理单个Message超过1M的情景,详见Large Data Sets。
进一步阅读
- .proto指南 https://developers.google.com/protocol-buffers/docs/proto
- .proto规范 https://developers.google.com/protocol-buffers/docs/style
- 序列化编码方式 https://developers.google.com/protocol-buffers/docs/encoding
- 教程 https://developers.google.com/protocol-buffers/docs/tutorials
- 接口文档 https://developers.google.com/protocol-buffers/docs/reference/overview
- Protobuf benchmarking https://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
阅读资料
Google Protocol Buffers介绍的更多相关文章
- Google Protocol Buffers 入门
Google Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的 ...
- C# 使用Google Protocol Buffers
Google Protocol Buffers 使用3.0版本 下载protoc.exe 下载链接 https://github.com/protocolbuffers/protobuf/releas ...
- Protocol Buffers介绍及例子
Protocol Buffers介绍及例子 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或数据交换格式.可用于通讯协 ...
- Google Protocol Buffers 快速入门(带生成C#源码的方法)
Google Protocol Buffers是google出品的一个协议生成工具,特点就是跨平台,效率高,速度快,对我们自己的程序定义和使用私有协议很有帮助. Protocol Buffers入门: ...
- 开源点评:Protocol Buffers介绍
今天来介绍一下“Protocol Buffers”(下面简称protobuf)这个玩意儿.本来俺在构思“生产者/消费者模式 ”系列的下一个帖子:关于生产者和消费者之间的传输数据格式.因为里面扯到了pr ...
- 【神经网络与深度学习】Google Protocol Buffer介绍
简介 什么是 Google Protocol Buffer? 假如您在网上搜索,应该会得到类似这样的文字介绍: Google Protocol Buffer( 简称 Protobuf) 是 Googl ...
- Protocol buffers 介绍
Protocol buffers和mxl一样在序列化数据结构时很灵活.高效和智能,但是它的优势在于定义文件更小,读取速度更快,使用更加简单.目前protocol buffers支持C++.java和p ...
- Protocol Buffers介绍
基本概念 Protocol Buffers(以下简称PB)是一种独立于语言.独立于开发平台.可扩展的序列化数据结构框架,它常常被用在通信.数据序列化保存等方面. PB是一种敏捷.高效.自动化的用于对数 ...
- Google Protocol Buffers简介
什么是 protocol buffers ? Protocol buffers 是一种灵活.高效的序列化结构数据的自动机制--想想XML,但是它更小,更快,更简单.你只需要把你需要怎样结构化你的数据定 ...
随机推荐
- postman发送post请求
在地址栏里输入请求url:http://127.0.0.1:8081/getuser 选择“POST”方式, 点击''body", ''form-data", 添加key:user ...
- 跟 Google 学 machineLearning [1] -- hello sklearn
时至今日,我才发现 machineLearning 的应用门槛已经被降到了这么低,简直唾手可得.我实在找不到任何理由不对它进入深入了解.如标题,感谢 Google 为这项技术发展作出的贡献.当然,可能 ...
- nginx内置预定义变量
nginx的配置文件中可以使用的内置变量以美元符$开始,也有人叫全局变量.其中,部分预定义的变量的值是可以改变的. $arg_PARAMETER 这个变量值为:GET请求中变量名PARAMETER参数 ...
- JS:指定FPS帧频,requestAnimationFrame播放动画
Flash制作动画,最基础的概念就是帧,但在Flash中,帧频的控制比较简单,只需要编译前指定一下目标帧频就可以了. 实际运行时,不需要我们关心定时器的问题,flash player会定时触发Ente ...
- 使用Dom4j创建xml文档
我们学习dom4j为的就是使用它来创建XML文档.读取文档等更为方便,下面通过一个实例来展示如何通过dom4j去创建XML文档.展示怎样通过两种方式去创建元素,可以直接通过addElement方法返回 ...
- RHEL7 Apache 服务测试
把防火墙和selinux关闭,这样试验过程中就不用配置相关策略了. 实验一.安装apache,并提供服务 在RHEL1上 #yum install -y httpd #echo basictest & ...
- 解决打开bootstrap模态框抖动问题
//打开模态框 function modalOpen(){ $('body').css("overflow", "hidden"); } //关闭模态框 fun ...
- Raspberry pi 使用python+pySerial实现串口通信(转)
Raspberry pi 使用python+pySerial实现串口通信 转:http://blog.csdn.net/homeway999/article/details/8642353 目录( ...
- 【转】IOCP创建
转自:http://www.cmnsoft.com/wordpress/?p=248 感谢原作者.我在此整理一下: 完成端口(IOCP)是WINDOWS平台上特有的一种技术.要使用IOCP技术,就要用 ...
- HDU 3584 Cube (三维数状数组)
Cube Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submi ...