Google Protocol Buffer的安装与.proto文件的定义
什么是protocol Buffer呢?
Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准.
我理解的就是:它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。方便文件的存储与网络传输.
我们自己就不用定义它们的存储与传输协议了.
怎么使用protobuf呢?
第一步, 写一个proto的文件 .定义你需要的数据结构.
每二步, 使用你想要用的语言的proto文件编译器把写的proto文件编译为目标语言的相关类. (目前google提供了 C++、Java、Python 三种语言的 API).
第三步, 把第二步生成的类包含到你写的程序中, 就可以使用它了.
看个基于C++主语言的例子,下面是一个.proto文件,
package information // 定义了package的名字 message Person { required ; required int32 id = ; optional ; enum PhoneType { MOBILE = ; HOME = ; WORK = ; } message PhoneNumber { required ; optional PhoneType type = [default = HOME]; } repeated PhoneNumber phone = ; }当我们命名这个文件时,用一个良好的命名习惯: 以这个的格式,packagename.MessageName.proto,所以这里的话,我们可以把这个文件命名为 information.Person.proto
然后,我们把.proto文件用编译器编译成C++的代码以后生成了两个文件:information.Person.h和information.Person.cc文件.
现在我们就可以用它了.
如定义一个Person的类对象,然后设置它里面的值(通过类的方法),populate,
Person person; person.set_name("John Doe"); person.set_id(); person.set_email("jdoe@example.com"); fstream output("myfile", ios::out | ios::binary); person.SerializeToOstream(&output); //把它序列化到输入输出流中,这里就是写文件中了.然后呢,我们可以从文件中再次retrieve出来 .
fstream input("myfile", ios::in | ios::binary); //读出文件 Person person; person.ParseFromIstream(&input); //反序列化它 cout << "Name: " << person.name() << endl; cout << "E-mail: " << person.email() << endl;
protobuf的安装:
方法一: 如果你用的ubuntu或debian的话,可以运行: sudo apt-get install protobuf-complier 命令直接安装.
方法二: 可以参考这里,https://github.com/google/protobuf,里面是什么我没有怎么仔细看哦,如果想简单安装的话,可以来这里下载protobuf-2.5.0tar.gz, 链接为:http://pan.baidu.com/s/1i5jsGiL,密码:50fo,下载完以后执行下面操作:
1,执行 tar –zxf protobuf-2.5.0.tar.gz 命令,解压文件;
2,执行 cd protobuf-2.5.0命令,进入目录。
3,执行 ./configure --prefix=加自己想安装到的绝对目录, 设置安装目录;
4,执行:make 进行编译
5, 执行: make check
6,执行: make install 进行安装;
最后呢, 加入它的环境变量,可以上系统找到它: export PATH= /home/work /protobuf/bin:$PATH
然后,你在shell里执行: protoc –version 命令,就会显示 libprotoc 2.5.0.
安装成功;
.proto文件的格式:
首先,我们定义一个.proto文件,下面的消息SearchRequest定义了3个字段.并以此为例:
message SearchRequest {
required ;
optional int32 page_number = ;
optional int32 result_per_page = ;
}
字段的类型: 可以为标量形式,如 string, int32等 ,也可以为复合形式,如枚举类型或其它的message类型,常见的类型如下(能看清哈):
分配的标记: 如上面所示,它们后面都有一个数字,干什么用的呢?它们的作用就是在以二进制形式的时候,可能通过这个分配的数字标记标识对应的字段,数字的范围可以从1至2次方-1. 1-15占一个字节(包括这个数字与字段类型),16-2047占两个字节.另个19000-19999是保留的数字标记. 在使用标记时,尽可能让经常出现的字段表示为1-15. 还有,我们要小的标记为将来使用.
字段的rules:
required: 在一个well-formed mmessage里,一定 要在这么一个字段.
optional: 表示可以存在可以不存在的字段.
repeated: 表示可以重复的字段,重复的次数可以为0哦. 另外,这些重复的values的顺序也会被保留下来.由于历史原因,为了让repeated的字段可以更好的encode,现在的新代码都会使一个选项[packed = true],如: repeated int32 samples = 4 [packed=true];
注意:当使用required字段的时候,要特征特别特别的小心哦,为什么呢?当我们在一个meassage里面定义了required字段的时候,如果我们有时候不想写它或着发送requied字段的时候,这时候就会出现问题,old readers会认为这个message不完整,它们就会把拒绝或着丢掉它. 所以,google的很多工程师认为,required的good 小于 harm, 所以他们选择只用optional 和repeated.
我们可以在一个.proto文件里面定义多个message.在.proto文件里面,我们用 // 来增加注释.
保留字段:在我们在删除或者注释了一个字段后,如果后来有别人使用了我们的.proto文件,为了防止别人再用我们删除或着注释过的字段的标记或名字时出现访问时的数据错误,我们应该保留我们使用过的字段的标记或名字.方法如下:
message Foo { reserved , , to ; reserved "foo", "bar"; } //注意:我们不能把标记与名字和放到一个 reserved里.
对于optional 字段, 我们可以设置它的默认值.当optional字段没有一个value的时候,就用默认的value代替.格式比如:
optional int32 result_per_page = []; //就就是默认10了.另外,如果我们没有设置认字段的时候,它会根据类型,设置系统的默认value. 对于 string, 默认为空字符, 对于bool类型, 默认为 false , 对于 数字类型,默认为0, 对于枚举类型,默认列表里的第一个值(所以啊,设置枚举类型时,一定特别注意啦)
message SearchRequest { required ; optional int32 page_number = ; optional int32 result_per_page = []; enum Corpus { UNIVERSAL = ; WEB = ; IMAGES = ; LOCAL = ; NEWS = ; PRODUCTS = ; VIDEO = ; } optional Corpus corpus = [default = UNIVERSAL]; }
1. 我们可以在枚举变量里面定义一个变量的别名,方法是我们把不同变量名的变量值定义成一样的,并且设置 变量 allow_alias 变true.如:
enum EnumAllowingAlias { option allow_alias = true; //一定变忘了,要不会出错的. UNKNOWN = ; STARTED = ; //下面的变量的值都为1 RUNNING = ; }2. 枚举类型的值应该为一个32位的整数, 由于枚举类型的值在encoding时,为变长整数的编码方式,对于 负数来说效率是很低的,所以不建议用负数作为值.
3. 我们可以把枚举类型定义在一个message里面,也可以定义在外面,这样的话,在一个.proro文件里,所有的message都可以使用它. 另外,也可以把一个枚举类型定义在其它的.proto文件里,使用的时候的syntax为:
MessageType.EnumType.
我们可以使用一个message类型作为一个字段的type.
message SearchResponse { repeated Result result = ; } message Result { required ; optional ; repeated ; }
Importy语句:
当我们想使用别的 .proto文件里定义的message的时候怎么办呢? 我们可以像在C/C++里导入头文件一样,使用import语句,可以把别的.proto文件导入进来. 如:
import "myproject/other_protos.proto";默认地,我们只能使用直接导入的.proto文件,(即,如果我们import的一个文件里又import了其它.proto文件,但是我们不能使用间接使用哦). 不过有一个方法, 可以让我们做到传递式的引用.即, import pulic notion.
// 第一个 .proto文件的位置; //各种定义;// 第二个.proto文件 import public "第一个文件" import "其它文件"// 各种定义// 第三个.proto文件 import "第二个文件" //这是,我们可以使用第一个文件里的定义,第二个文件里的定义,但是不能使用其它文件里的定义import文件时的搜索路经: 可以通过 –I/ –proto_path指定搜索路经, 或着it looks in the directory in which the compiler was invoked.
怎么更新一个 .proto文件
(对于这部分现在不先看,因为用不着,要不看了也没有用.)
Oneof 的使用:
当我们有很多可选的字段的时候,并且在很多情况下最多有一个字段被使用时,这时我们可以作用Oneof.如:
message SampleMessage { oneof test_oneof { ; SubMessage sub_message = ; } }这时,在Oneof 里的所有字段不会包含 required, optional ,或repeated 类型说明符. 它们共用一个memory,所示可以节约内存.我们可以使用case()或WhichOneof()方法来查看哪一个value被使用(使用哪一个方法决定我们使用的语言).
注意:当我们为Oneof里的多个字段设置值时,只有最后一个被设置的字段被保留下来了.
注意它的后向兼容性。
Map的使用:
可以增加一个map:
map<key_type, value_type> map_field = N;其中,key_type,可以为任意的整数或者string类型, value_type,可以为任意的类型. 如下为一个例子,我们把一个 Project的 Message类型与一个 string的value值相綁定了。
map<;
Packages:
它存在的目的是为了防止在.proto文件里的名字冲突. 就像C++里的命名空间差不多.如下所示:
首先我们定义了一个这个:
package foo.bar; message Open { ... }然后再我们使用它的时候,我们要这么用:
message Foo { ... required foo.bar.Open open = ; //看到没,我们要加上它的package 的名字. ... }
另外,还有很多可以选的选项,见:https://developers.google.com/protocol-buffers/docs/proto.
参考资料:
https://developers.google.com/protocol-buffers/
http://blog.csdn.net/huguoping830623/article/details/45482725
http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
最后,如果你觉得以上内容对你提供了实质的帮助, 如果你有钱的话,如果你愿意的话,可以打赏一下我这个穷学生哦,资助我买几本书.
钱也不用太多哦, 您可以选择:2毛,5毛、1元。(靠知识创造价值, 靠知识改变生活 ——爱你们的杰克船长,么么哒)

Google Protocol Buffer的安装与.proto文件的定义的更多相关文章
- Google Protocol Buffer的安装与.proto文件的定义(转)
转自(https://www.cnblogs.com/yinheyi/p/6080244.html) 什么是protocol Buffer呢? Google Protocol Buffer( 简称 P ...
- Google Protocol Buffer
Google Protocol Buffer(protobuf)是一种高效且格式可扩展的编码结构化数据的方法.和JSON不同,protobuf支持混合二进制数据,它还有先进的和可扩展的模式支持.pro ...
- Google Protocol Buffer安装编译及使用
近期玩了玩谷歌的Protocol Buffer.以下就简介下 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准.眼下已经正在使用的 ...
- Google Protocol Buffer 的使用和原理[转]
本文转自: http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构 ...
- Google Protocol Buffer 的使用和原理
Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...
- 【Google Protocol Buffer】Google Protocol Buffer
http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Google Protocol Buffer 的使用和原理 Protocol Buffers ...
- 在 go/golang语言中使用 google Protocol Buffer
怎么在go语言中实用google protocol Buffer呢? 现在的潮流趋势就是一键搞定,跟ubuntu安装软件一样 go get code.google.com/p/goprotobuf/{ ...
- 前端后台以及游戏中使用Google Protocol Buffer详解
前端后台以及游戏中使用Google Protocol Buffer详解 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更 ...
- 转Google Protocol Buffer 的使用和原理
Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...
随机推荐
- (转)php自己创建框架
前言 说到写PHP的MVC框架,大家想到的第一个词--“造轮子”,是的,一个还没有深厚功力的程序员,写出的PHP框架肯定不如那些出自大神们之手.经过时间和各种项目考验的框架.但我还是准备并且这么做了, ...
- 关于HTML5中video标签的奇怪现象
很多人刚开始学习html5 的时候在使用video标签时会出现这样的情况: 发现video标签在网页中播放时只有声音但是没有图像,如: <!DOCTYPE html> <html&g ...
- Fiddler- -Composer创建和发送HTTP Request
Fiddler的功能还有很多, 很多功能都没有被挖掘出来.这次我们介绍Fiddler中的一个非常有用的功能Composer,是用来创建和发送HTTP Request的.Composer的使用方法很简单 ...
- centos7下快速安装mysql
CentOS 7的yum源中貌似没有正常安装MySQL时的mysql-sever文件,需要去官网上下载 # wget http://dev.mysql.com/get/mysql-community- ...
- C#.NET序列化XML、JSON、二进制微软自带DLL与newtonsoft(json.net)
序列化是将对象转换成另一种格式(XML.json.二进制byte[]) JSON序列化 .NET中有三种常用的JSON序列化的类,分别是: Newtonsoft.Json.JsonConvert类(推 ...
- linux----------纯净的centos7.0上安装lnmp环境的步骤
1.先看下screen -S lnmp 命令是否存在,不存在则安装.这个是个什么东东呢?百度一下( GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接 ...
- jqgrid定义多选操作
先定义: var SelectRowIndx; 然后加入以下属性: multiselect: true, onSelectRow: function () { SelectRowIndx = G ...
- Coursera台大机器学习课程笔记3 – 机器学习的可能性
提纲: 机器学习为什么可能? 引入计算橙球概率问题 通过用Hoeffding's inequality解决上面的问题,并得出PAC的概念,证明采样数据学习到的h的错误率可以和全局一致是PAC的 将得到 ...
- APP-SQLAP-10771:Could not reserve record (匹配PO时候)
,) SID, substr(C.SERIAL#,,) SERIAL#, substr(B.,) OBJ_NAME, C.STATUS, C.USERNAME, c.action, C.USER#, ...
- [ruby]Windows Ruby安装步骤
Windows Ruby 安装步骤 准备工作: 1.http://rubyinstaller.org/downloads/ 下载选择Ruby 1.9.3 2.http://rubyinstaller. ...
