什么是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文件的定义的更多相关文章

  1. Google Protocol Buffer的安装与.proto文件的定义(转)

    转自(https://www.cnblogs.com/yinheyi/p/6080244.html) 什么是protocol Buffer呢? Google Protocol Buffer( 简称 P ...

  2. Google Protocol Buffer

    Google Protocol Buffer(protobuf)是一种高效且格式可扩展的编码结构化数据的方法.和JSON不同,protobuf支持混合二进制数据,它还有先进的和可扩展的模式支持.pro ...

  3. Google Protocol Buffer安装编译及使用

    近期玩了玩谷歌的Protocol Buffer.以下就简介下 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准.眼下已经正在使用的 ...

  4. Google Protocol Buffer 的使用和原理[转]

    本文转自: http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构 ...

  5. Google Protocol Buffer 的使用和原理

    Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...

  6. 【Google Protocol Buffer】Google Protocol Buffer

    http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Google Protocol Buffer 的使用和原理 Protocol Buffers ...

  7. 在 go/golang语言中使用 google Protocol Buffer

    怎么在go语言中实用google protocol Buffer呢? 现在的潮流趋势就是一键搞定,跟ubuntu安装软件一样 go get code.google.com/p/goprotobuf/{ ...

  8. 前端后台以及游戏中使用Google Protocol Buffer详解

    前端后台以及游戏中使用Google Protocol Buffer详解 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更 ...

  9. 转Google Protocol Buffer 的使用和原理

    Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它 ...

随机推荐

  1. Unit02-OOP-对象和类,数组(下)

    Unit02-OOP-对象和类,数组(下) 1.方法的签名: 方法名+参数列表 2.方法的重载(Overload):  1)发生在一个类中,方法名称相同,参数列表不同  2)编译器在编译时自动根据签名 ...

  2. C# 遍历类的属性并取出值

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    今天有点胡思乱想,想遍历MVC Model的属性并 ...

  3. 用 python 实现一个多线程网页下载器

    今天上来分享一下昨天实现的一个多线程网页下载器. 这是一个有着真实需求的实现,我的用途是拿它来通过 HTTP 方式向服务器提交游戏数据.把它放上来也是想大家帮忙挑刺,找找 bug,让它工作得更好. k ...

  4. 部署keepalive+lvs

    部署keepalive+lvs 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.       欢迎降入:高级运维工程师之路 598432640     安装LVS的步骤我已经在另外的一 ...

  5. .NET开发实战1-军队未出,粮草先行。

    马上期末考试了,会想起这个学习的自己.一直都在一个人搞java的研究,C#课也没怎么去上.所以在这里想弥补一下自己没去上课的原因,也希望老师能够理解这个还在迷茫的我. 正所谓,军队未出粮草先行,所以我 ...

  6. 15. 星际争霸之php设计模式--策略模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. windows系统上安装与使用Android NDK r5 (转)

    windows系统上安装与使用Android NDK r5  很早就听说了android的NDK应用,只是一直没有时间去研究,今天花了点时间在windows平台搭建了NDK环境,并成功运行了第一个简单 ...

  8. degign new theme for Filezilla(Mac OS X)

    the theme directory is located at Filezilla.app/Contents/SharedSupport/resources/ the dirs (excludin ...

  9. Hadoop 2.0命令手册

    1.       FS Shell 1.1     简介 调用文件系统(FS)Shell命令应使用 bin/hadoop fs <args>的形式. 所有的的FS shell命令使用URI ...

  10. shell脚本 空格

    1.定义变量时, =号的两边不可以留空格. eg: gender=femal----right gender =femal---–wrong gender= femal---–wrong 2.条件测试 ...