浅谈Google Protocol Buffers(一)

发布时间:2018-01-10 12:46:46编辑:丝画阁阅读(996)

Protocol buffers

Protocol Buffers,是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。

它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。

通过它,你可以定义你的数据的结构,并生成基于各种语言的代码。这些你定义的数据流可以轻松地在传递并不破坏你已有的程序。并且你也可以更新这些数据而现有的程序也不会受到任何的影响。

Protocol Buffers经常被简称为protobuf。

通常,编写一个protocol buffers应用需要经历如下三步:

1、定义消息格式文件,最好以proto作为后缀名

2、使用Google提供的protocol buffers编译器来生成代码文件,一般为.h和.cc文件,主要是对消息格式以特定的语言方式描述

3、使用protocol buffers库提供的API来编写应用程序

Protocol buffers的优点

同XML相比,Protocol buffers在序列化结构化数据方面有许多优点:

1. 更简单

2. 数据描述文件只需原来的1/10至1/3

3. 解析速度是原来的20倍至100倍

4. 减少了二义性

5. 生成了更容易在编程中使用的数据访问类

6、支持多种编程语言

定义Proto文件

浅谈Google Protocol Buffers(一)

对于每个字段而言都有一个修饰符(required/repeated/optional)、字段类型(bool/string/bytes/int32等)和字段标签(Tag)组成。

1)对于required的字段而言,初值是必须要提供的,否则字段的便是未初始化的。

2)对于optional的字段而言,如果未进行初始化,那么一个默认值将赋予该字段,当然也可以指定默认值,如上述proto定义中的PhoneType字段类型。

3)对于repeated的字段而言,该字段可以重复多个,google提供的这个addressbook例子便有个很好的该修饰符的应用场景,即每个人可能有多个电话号码。

其中字段标签标示了字段在二进制流中存放的位置,这个是必须的,而且序列化与反序列化的时候相同的字段的Tag值必须对应,否则反序列化会出现意想不到的问题。

编译proto文件,生成特定语言的数据定义代码

在定义好了proto文件,就可以将该文件作为protocol buffers编译器的输入文件,编译产生特定语言的数据定义代码文件了。本文主要是针对C++,所以使用编译器后生成的是.h与.cc的代码文件。对于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为例:

浅谈Google Protocol Buffers(一)

可以看出,对于每个字段会生成一个has函数(has_number)、clear清除函数(clear_number)、set函数(set_number)、get函数(number和mutable_number)。

而对于字段修饰符为repeated的字段生成的函数,则稍微有一些不同,如phone字段,则编译器会为其产生如下的代码:

浅谈Google Protocol Buffers(一)

可以看出,set函数变成了add函数,这个其实很好理解。上面也说过,repeated修饰的字段在高级语言中的实现可能是个数组或动态数组,所以当然通过添加的方式来加入新的字段值。

本文到此结束,如果对您有些帮助,点一波关注吧,老铁!

关键字