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

原创 2015年07月10日 10:07:57
本文主要会介绍怎么使用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("zwg19891129@163.com");
    personMe->set_unsure("19bf173a0e87ab");
    
    //第二个联系人的数据定义与初始化
    Person  *personHim = addressBook.add_person();
    personHim->set_id(2);
    personHim->set_name("XXX");
    personHim->set_email("XXX@XXX.com");
    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);




         很容易看出,上述代码即在地址簿中添加了俩个联系人,然后又分别填充各个联系人的数据信息,通过上述代码一个地址簿的数据便准备好了。
        
        二、序列化数据 
        其实通过看编译器生成的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等方式都应该比较类似,所以感兴趣的朋友可以自己动手试试。   

手把手教你如何安装Protocol Buffer

前言 习惯用 Json、XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,...
  • carson_ho
  • carson_ho
  • 2017年04月17日 10:40
  • 13472

Google protocol buffer 的反射机制和应用

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反...
  • chengangdzzd
  • chengangdzzd
  • 2016年01月01日 23:38
  • 2032

快来看看Google出品的Protocol Buffer,别只会用Json和XML了

前言 习惯用 Json、XML 数据存储格式的你们,相信大多都没听过Protocol BufferProtocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格...
  • aptentity
  • aptentity
  • 2017年03月29日 23:20
  • 750

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

一、简单的介绍      Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++、Java以及Python语言,可以使用该技术来持久化数据或者序列化成网络传输的...
  • hustyangju
  • hustyangju
  • 2015年07月10日 10:02
  • 893

Google Protocol Buffer序列化入门实战(附源码)

Google Protocol Buffer入门实战(附源码)Google Protocol Buffer(后面简称PB)是Google开源的一款二进制序列化工具,占用空间小,传输效率高。最近由于项目...
  • u011116672
  • u011116672
  • 2016年08月09日 15:38
  • 2337

Google Protocol Buffer简介、开发指引及编码方式

总览: 开发引导: 欢迎来到protocol buffer开发文档。protocol buffers是一个语言无关、平台无关、序列化结构数据可扩展的用来协议交互、数据存储等的解决方案。 ...
  • u012398613
  • u012398613
  • 2014年10月27日 19:30
  • 815

Google protocol buffer 使用和原理浅析 And 进阶使用方式之PbCodec

Google Protocol Buffer又简称Protobuf,它是一种很高效的结构化数据存储格式,一般用于结构化数据的串行化,简单说就是我们常说的数据序列化。这种序列化的协议非常轻便高效,而且是...
  • linyousong
  • linyousong
  • 2016年07月03日 17:04
  • 5290

一个基于protocol buffer的RPC实现

一个基于protocol buffer的RPC实现 Protocol Buffer仅仅是提供了一套序列化和反序列化结构数据的机制,本身不具有RPC功能,但是可以基于其实现一套RP...
  • u010064842
  • u010064842
  • 2015年04月15日 22:52
  • 1292

Protocol Buffer简介、安装与使用

Protocol Buffer简介、安装与使用 1.Protobuf 简介 Google Protocol Buffer(简称Protobuf)是Google公司内部的混合语言数据标准,是一种轻便高...
  • liupenghui_200
  • liupenghui_200
  • 2016年06月19日 11:47
  • 3665

Protocol Buffer 序列化原理大揭秘 - 为什么Protocol Buffer性能这么好?

前言 习惯用 Json、XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,...
  • carson_ho
  • carson_ho
  • 2017年04月24日 09:19
  • 23840
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:google protocol buffer的原理和使用(二)
举报原因:
原因补充:

(最多只允许输入30个字)