google protocol buffer的原理和使用(一)
一、简单的介绍
Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++、Java以及Python语言。能够使用该技术来持久化数据或者序列化成网络传输的数据。相比較一些其它的XML技术而言。该技术的一个明显特点就是更加节省空间(以二进制流存储)、速度更快以及更加灵活。
通常,编写一个protocol buffers应用须要经历例如以下三步:
1、定义消息格式文件。最好以proto作为后缀名
2、使用Google提供的protocol buffers编译器来生成代码文件,一般为.h和.cc文件,主要是对消息格式以特定的语言方式描写叙述
3、使用protocol buffers库提供的API来编写应用程序
二、定义Proto文件
proto文件即消息协议原型定义文件,在该文件里我们能够通过使用描写叙述性语言,来良好的定义我们程序中须要用到数据格式。
首先我们能够通过Google在线文档上提供的一个电话簿的样例来了解下。只是略微加了点修改。
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;
required bytes unsure = 5; //Add byte array here
}
message AddressBook {
repeated Person person = 1;
}
诚如你看到的一样,消息格式定义非常easy。对于每一个字段而言都有一个修饰符(required/repeated/optional)、字段类型(bool/string/bytes/int32等)和字段标签(Tag)组成。
三个修饰符从词义上能够非常清楚的弄明确。
1)对于required的字段而言,初值是必需要提供的,否则字段的便是未初始化的。
在Debug模式的buffer库下编译的话,序列化话的时候可能会失败,并且在反序列化的时候对于该字段的解析会总是失败的。所以,对于修饰符为required的字段,请在序列化的时候务必给予初始化。
2)对于optional的字段而言,假设未进行初始化。那么一个默认值将赋予该字段。当然也能够指定默认值。如上述proto定义中的PhoneType字段类型。
3)对于repeated的字段而言,该字段能够反复多个,google提供的这个addressbook样例便有个非常好的该修饰符的应用场景,即每一个人可能有多个电话号码。在高级语言里面,我们能够通过数组来实现,而在proto定义文件里能够使用repeated来修饰,从而达到同样目的。当然。出现0次也是包括在内的。
当中字段标签标示了字段在二进制流中存放的位置,这个是必须的,并且序列化与反序列化的时候同样的字段的Tag值必须相应,否则反序列化会出现意想不到的问题。
三、编译proto文件。生成特定语言数据的数据定义代码
在定义好了proto文件。就能够将该文件作为protocol buffers编译器的输入文件。编译产生特定语言的数据定义代码文件了。本文主要是针对C++语言,所以使用编译器后生成的是.h与.cc的代码文件。对于C++、Java还有Python都有各自的编译器。下载地址:http://code.google.com/p/protobuf/downloads/list
当你下载完了相应的编译器二进制文件后。就能够使用下列命令来完毕编译过程:
protoc.exe -proto_path=SRC --cpp_out=DST SRC/addressbook.proto
当中--proto_path指出proto文件所在的文件夹,--cpp_out则是生成的代码文件要放的文件夹,最后的一个參数指出proto文件的路径。如上述命令中能够看出,将SRC文件夹下的addressbook.proto编译后放在DST文件夹下。应该会生成addressbook.pb.h和addressbook.pb.cc文件(/Files/royenhome/addressbook.rar)。
通过查看头文件,能够发现针对每一个字段都会大致生成例如以下几种函数,以number为例:
// required string number = 1;
inline bool has_number() const;
inline void clear_number();
inline const ::std::string& number() const;
inline void set_number(const ::std::string& value);
inline void set_number(const char* value);
inline ::std::string* mutable_number();
能够看出。对于每一个字段会生成一个has函数(has_number)、clear清除函数(clear_number)、set函数(set_number)、get函数(number和mutable_number)。这儿解释下get函数中的两个函数的差别,对于原型为const std::string &number() const的get函数而言,返回的是常量字段,不能对其值进行改动。可是在有一些情况下,对字段进行改动是必要的。所以提供了一个mutable版的get函数,通过获取字段变量的指针,从而达到改变其值的目的。
而对于字段修饰符为repeated的字段生成的函数。则略微有一些不同,如phone字段,则编译器会为其产生例如以下的代码:
// repeated .Person.PhoneNumber phone = 4;
inline int phone_size() const;
inline void clear_phone();
inline const ::google::protobuf::RepeatedPtrField< ::Person_PhoneNumber >& phone() const;
inline ::google::protobuf::RepeatedPtrField< ::Person_PhoneNumber >* mutable_phone();
inline const ::Person_PhoneNumber& phone(int index) const;
inline ::Person_PhoneNumber* mutable_phone(int index);
inline ::Person_PhoneNumber* add_phone();
能够看出,set函数变成了add函数,这个事实上非常好理解。
上面也说过。repeated修饰的字段在高级语言中的实现可能是个数组或动态数组,所以当然通过加入的方式来加入新的字段值。而起get函数也变化非常大。这个也不用多说了。
好了。本文主要是对了解protocol buffer作了些简单的介绍,当然更具体的还是看官方文档。
google protocol buffer的原理和使用(一)的更多相关文章
- google protocol buffer的原理和使用(二)
本文主要会介绍怎么使用Google Protocol的Lib来序列化我们的数据,方法非常多种,本文仅仅介绍当中的三种.其它的方法读者能够通过自行研究摸索.但总的来说,序列化数据总的来说分为下面俩步: ...
- google protocol buffer的原理和使用(三)
介绍下怎么反序列化GoogleBuffer数据.并在最后提供本系列文章中所用到的代码整理供下载. 上一篇文章介绍了如何将数据序列化到了addressbook.data中.那么对于接受方而言该怎么解析出 ...
- google protocol buffer的原理和使用(四)
有个电子商务的系统(如果用C++实现).当中的模块A须要发送大量的订单信息给模块B.通讯的方式使用socket. 如果订单包含例如以下属性: ----------------------------- ...
- Google Protocol Buffer 的使用和原理
Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...
- 转Google Protocol Buffer 的使用和原理
Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...
- Google Protocol Buffer 的使用和原理[转]
本文转自: http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构 ...
- Google Protocol Buffer 的使用和原理(无论对存储还是数据交换,都是个挺有用的东西,有9张图做说明,十分清楚)
感觉Google Protocol Buffer无论对存储还是数据交换,都是个挺有用的东西,这里记录下,以后应该用得着.下文转自: http://www.ibm.com/developerworks/ ...
- (转)Google Protocol Buffer 的使用和原理
转自:https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html 简介 什么是 Google Protocol Buffer? ...
- Google Protocol Buffer 协议
1. Protocol Buffers 简介 Protocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,类似于XML能够将结构化 ...
随机推荐
- Experimental considerations
先知 重金属颗粒与气孔大小 气孔位置.密度与开合时间 角质层厚度 意外 叶子第二天掉落 样本没有放冰箱 高光谱仪器损坏 天气下雨/雪 仪器预约 楼顶/实验室门卡提前一天预约 光合仪提前一天预约 ASD ...
- 【02】你是如何理解 HTML 语义化的,有什么好处
[02]你是如何理解 HTML 语义化的 01,语义化,就是通过HTML标签来表示页面包含的信息. 02,其中有HTML标签的语义化和CSS命名的语义化. 03,HTML标签语义化的的含义是: ...
- Head First HTML5 Programming笔记--chapter2 介绍Javascript和DOM
你已经了解了HTML标记(也称为结构),而且知道了CSS样式(也称为表示),剩下的就是Javascript(也称为行为). JavaScript的工作方式 1. 编写 你创建HTML标记和JavaSc ...
- python算法-插入排序
插入排序 一.核心思想:在一个有序的数组中,通过逐一和前面的数进行比较,找到新数的位置. 例子:数组有有一个数21 插入一个3,3<21,因此结果为 3,21 再插入一个34,34>21, ...
- iOS学习笔记06-手势识别
一.UIGestureRecognizer简单介绍 我们已经学习了触摸事件处理,但触摸事件处理起来很麻烦,每个触摸事件处理都需要实现3个touches方法,比较繁琐,实际上我们可以使用更加简单的触摸事 ...
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...
- 【容斥】HDU 4135 Co-prime
acm.hdu.edu.cn/showproblem.php?pid=4135 [题意] 询问[a,b]中与n互质的数有多少个 [思路] 考虑[1,m]中与n互质的数有多少个,答案就是query(b) ...
- LINUX支持哪些文件系统
我们在Linux中常用的文件系统主要有ext3.ext2及reiserfs :Windows和Dos常用的文件系统是fat系列(包括fat16及fat32等)和ntfs 文件系统:光盘文件系统是ISO ...
- javaScriptCore 实战与小结
源码在这,看不懂的直接撸源码就行,转载声明出处 原生调用JS的大致流程,做了个思维简图 这是代码流程 // JS数据 func getJSVar() { let context: JSContex ...
- 送外卖(codevs 2800)
题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一 ...