google protocol buffer的原理和使用(二)

本文主要会介绍怎么使用Google Protocol的Lib来序列化我们的数据,方法非常多种,本文仅仅介绍当中的三种。其它的方法读者能够通过自行研究摸索。但总的来说,序列化数据总的来说分为下面俩步:

1)使用数据源填充数据结构,不管数据源来自文件还是内存还是标准输入

2)利用Lib提供的序列化接口将数据结构序列化,然后存储在内存或者磁盘上

一、填充数据结构

从数据源中获取数据。这儿的数据源可能来自磁盘上的一个文件或者内存中存储的一段数据或者来自标准输入的数据。我们须要做的就是,将AddressBook这个数据结构中的各个字段填充。本例中是通过AddressBook提供的add_person函数来获得一个Person的指针,从而对其进行填充,例如以下代码所看到的:

//地址簿数据定义

AddressBook    addressBook;

//第一个联系人的数据定义与初始化

Person    *personMe  = addressBook.add_person();

personMe->set_id(1);

personMe->set_name("royen");

personMe->set_email("[email protected]");

personMe->set_unsure("19bf173a0e87ab");

//第二个联系人的数据定义与初始化

Person  *personHim = addressBook.add_person();

personHim->set_id(2);

personHim->set_name("XXX");

personHim->set_email("[email protected]");

personHim->set_unsure("19bf173a0e87ab");

//personMe的手机号码数据定义与初始化

Person_PhoneNumber *phoneNumberMobile = personMe->add_phone();

phoneNumberMobile->set_number("15996110120");

phoneNumberMobile->set_type(Person_PhoneType_MOBILE);

//personMe的座机号码数据定义与初始化

Person_PhoneNumber *phoneNumberHome   = personMe->add_phone();

phoneNumberHome->set_number("0256110120");

phoneNumberHome->set_type(Person_PhoneType_HOME);

//personHim的一个号码数据定义与初始化

Person_PhoneNumber *phoneNumberHim      = personHim->add_phone();

phoneNumberHim->set_number("15996111111");

phoneNumberHim->set_type(Person_PhoneType_HOME);

非常easy看出,上述代码即在地址簿中加入了俩个联系人。然后又分别填充各个联系人的数据信息,通过上述代码一个地址簿的数据便准备好了。

二、序列化数据

事实上通过看编译器生成的AddressBook这个类所提供的方法名,既能够大致知道有哪些序列化的方式。例如以下所看到的:

从上图能够看出。可利用序列化的方法非常多,本文中主要使用SerializeToString、SerializeToCodedStream以及SerializeToOstream来完毕序列化。

以下就分别就这几种方式来介绍下:

1) SerializeToCodedStream方式

首先能够知道该函数的原型是bool SerializeToCodedStream(std::ostream *),所以使用该函数须要结合C++的fstream流。代码例如以下:

//方法一: 使用SerializePartialToOstream来序列化,注意ios::binary以二进制流写入文件

fstream  fserial("addressbook.data",ios::out | ios::trunc | ios::binary);

if (!addressBook.SerializePartialToOstream(&fserial))

{

cerr<<"Failed to serial address book data!\n";

return;

}

cout<<"Serial address book data successfully!\n";

fserial.close();

fserial.clear();

能够看出,採用这样的方法相当的便捷,并且也非常简洁,但有个缺点就是输出到文件的编码格式不好控制,所以能够使用以下介绍的这样的方法。

2)SerializeToString方式

函数原型为bool SerializeToString(std::string* output) ,所以能够讲填充在数据结构AddressBook中的数据取出存到一个string对象中,然后再以二进制流的方式将其写入到磁盘文件里。代码例如以下:

FILE    *g_AddressBook = fopen("addressbook.data","wb,ccs = UNICODE");

if( NULL == g_AddressBook )

{

cerr<<"Create addressbook.data failed!\n";

return ;

}

string    serialStream = "";

if( !addressBook.SerializePartialToString(&serialStream) )

{

cerr<<"Failed to serial addressbook data!\n";

return;

}

fwrite( serialStream.c_str(),sizeof(char),addressBook.ByteSize(),g_AddressBook);

cout<<"serial address successfully!\n";

if( g_AddressBook )

{

fclose(g_AddressBook);

g_AddressBook = NULL;

}

上述代码略微繁琐了点。可是也是一种序列化的方式。通过结合使用C库中的文件操作函数,能够更方便的定制输出文件。

3)SerializeToCodedStream方式

该方式主要指用到的google buffer的库中提供的一组数据流操作对象。在使用这些对象之前须要引入一些头文件。例如以下所看到的:

#include <google/protobuf/io/zero_copy_stream_impl.h>

#include <google/protobuf/io/zero_copy_stream.h>

#include <google/protobuf/io/coded_stream.h>

using namespace::google::protobuf::io;

该方式也结合C库的open与write函数,序列化部分的代码例如以下:

int fd  = _open("addressbook.data", _O_WRONLY |_O_CREAT| _O_BINARY, _S_IREAD|_S_IWRITE);

if( -1 == fd )

{

cerr<<"Create addressbook.data failed!\n";

return ;

}

char tmpArr[MAX_SIZE];

memset(tmpArr,0,sizeof(tmpArr));

ZeroCopyOutputStream *raw_output = new ArrayOutputStream(tmpArr,addressBook.ByteSize()+1);

CodedOutputStream* coded_output = new CodedOutputStream(raw_output);

if( !addressBook.SerializeToCodedStream( coded_output ))

{

cerr<<"Fail to serial addressbook data!\n";

return;

}

_write(fd,tmpArr,addressBook.ByteSize()+1);

cout<<"serial address successfully!\n";

delete coded_output;

delete raw_output;

close(fd);

本文临时介绍这三种序列化话方式,还有像SerializeToArray以及SerializeToFileDescriptor等方式都应该比較类似。所以感兴趣的朋友能够自己动手试试。

时间: 2024-10-06 16:42:26

google protocol buffer的原理和使用(二)的相关文章

google protocol buffer的原理和使用(三)

介绍下怎么反序列化GoogleBuffer数据,并在最后提供本系列文章中所用到的代码整理供下载. 上一篇文章介绍了怎样将数据序列化到了addressbook.data中,那么对于接受方而言该怎么解析出原本的数据呢.同样,protoc编译器生成的代码文件中提供了反序列化的接口,基本上和序列化的函数对应的,如下图所示: 上文中采用了SerializeToOstream.SerializeToString.SerializeToCodedStream来序列化数据的,反序列化反其道行之即可.本文反序列化

google protocol buffer的原理和使用(四)

有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket. 假设订单包括如下属性: -------------------------------- 时间:time(用整数表示) 客户id:userid(用整数表示) 交易金额:price(用浮点数表示) 交易的描述:desc(用字符串表示) -------------------------------- 如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto

Google protocol buffer 使用和原理浅析 - 附带进阶使用方式

Protocol Buffer ??Google Protocol Buffer又简称Protobuf,它是一种很高效的结构化数据存储格式,一般用于结构化数据的串行化,简单说就是我们常说的数据序列化.这种序列化的协议非常轻便高效,而且是跨平台的,目前已支持多种主流语言(3.0版本支持C++, JAVA, C#, OC, GO, PYTHON等). ??通过这种方式序列化得到的二进制流数据比传统的XML, JSON等方式的结果都占用更小的空间,并且其解析效率也更高,用于通讯协议或数据存储领域是非常

Google Protocol Buffer 的使用和原理

Google Protocol Buffer 的使用和原理 1.https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ 2.参考资料:http://blog.csdn.net/educast/article/details/24764205 3.github源码:https://github.com/google/protobuf 4谷歌:https://developers.google.com/protocol-buffers/

转Google Protocol Buffer 的使用和原理

Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它可用于通讯协议.数据存储等领域的语言无关.平台无关.可扩展的序列化结构数据格式.目前提供了 C++.Java.Python 三种语言的 API. 2010 年 11 月 18 日 内容 简介 一个简单的例子 和其他类似技术的比较 高级应用话题 Protobuf 的更多细节 结束语 参考资料 评论 在

【Google Protocol Buffer】Google Protocol Buffer

http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ Google Protocol Buffer 的使用和原理 Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式.它可用于通讯协议.数据存储等领域的语言无关.平台无关.可扩展的序列化结构数据格式.目前提供了 C++.Java.Python 三种语言的 API. 17 评论: 刘 明, 软件工程师, 上海交大电

Google protocol buffer使用笔记

一 下载 Google下载地址:https://developers.google.com/protocol-buffers/docs/downloads?hl=zh-CN Github下载地址:https://github.com/google/protobuf 我这里下载版本:protobuf-2.6.1.tar.gz 二 编译 1 解压 将上面的压缩包解压到文件夹 protobuf-2.6.1 中. 2 编译 2.1 在protobuf-2.6.1中,找到vsprojects/protob

Google Protocol Buffer 协议

1. Protocol Buffers 简介 Protocol Buffers (ProtocolBuffer/ protobuf )是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可以使用该技术来持久化数据或者序列化成网络传输的数据.主要用于数据存储.通信协议等方面.现阶段支持C++.JAVA.Python.Objective-C.C#.Javascript等6种编程语言.Googel 公司 2015-12-31 更新了最新的版本Version 3.0.0-bet

Netty使用Google Protocol Buffer完成服务器高性能数据传输

一.什么是Google Protocol Buffer(protobuf官方网站) 下面是官网给的解释: Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data. – think XML, but smaller, faster, and simpler. 协议缓冲区是一种和语言无关.平台无关的可扩展机制,用于序列化结构化的数据.相