zoukankan      html  css  js  c++  java
  • google protocol buffer的原理和使用(三)

    介绍下怎么反序列化GoogleBuffer数据。并在最后提供本系列文章中所用到的代码整理供下载。


         上一篇文章介绍了如何将数据序列化到了addressbook.data中。那么对于接受方而言该怎么解析出原本的数据呢。

    相同,protoc编译器生成的代码文件里提供了反序列化的接口,基本上和序列化的函数相应的,例如以下图所看到的:
           
          上文中採用了SerializeToOstream、SerializeToString、SerializeToCodedStream来序列化数据的,反序列化反其道行之就可以。本文反序列化採用ParseFromArray方式,从某个角度算是对上文的一个补充吧!
           反序列化也是分为两个步骤:
           1)将数据加载内存或者输入流 
           2)调用库提供的反序列化接口函数进行反序列化
          
           一、将数据加载 
           将数据从文件里读出时候,须要注意以二进制的模式打开。且编码格式要指定正确,例如以下所看到的:               


        FILE    *g_AddressBook = fopen("addressbook.data","rb,ccs=UNICODE");
        if( NULL == g_AddressBook )
        {
            cerr<<"Open addressbook.data failed! "<<endl;
            return ;
        }


        int lfilesize = 0;
        fseek( g_AddressBook,0,SEEK_END);
        lfilesize = ftell( g_AddressBook );
        fseek( g_AddressBook ,0,SEEK_SET );
        
        char *buffer =new char[lfilesize+1];
        if( NULL == buffer )
        {
            cerr<<"malloc memory error! ";
            return;
        }
        memset(buffer,'',sizeof(buffer));
        fread( buffer,sizeof(char),lfilesize,g_AddressBook);
        if( g_AddressBook )
        {
            fclose(g_AddressBook);
            g_AddressBook = NULL;
        }




                  
           二、反序列化
           上述代码将addressbook.data中的数据加载了buffer中,接着我们就能够将其作为參数传给ParseFromArray来反序列化。并格式化输出到控制台,例如以下:     


        AddressBook    addressBook;
        addressBook.par
        addressBook.Clear();


        if( !addressBook.ParseFromArray(buffer,lfilesize) )
        {
            cerr<<"Deserial from addressbook.data failed! ";
            return;
        }


        int personSize = addressBook.person_size();


        for( int i=0 ;i<personSize; i++ )
        {
            Person p = addressBook.person( i );
            cout<<"Person "<<i+1<<": id "<<p.id()<<" name: "<<p.name()<<" ";
            int phoneSize = p.phone_size();
            for( int j=0;j<phoneSize;j++ )
            {
                Person_PhoneNumber phone = p.phone(j);
                cout<<"Phone "<<j+1<<": Type: ";
                switch( phone.type())
                {
                case Person_PhoneType_MOBILE:
                    cout<<"Mobile Phone Number: "<<phone.number()<<endl;
                    break;
                case Person_PhoneType_HOME:
                    cout<<"Home Phone Number: "<<phone.number()<<endl;
                    break;
                case Person_PhoneType_WORK:
                    cout<<"Work Phone Number: "<<phone.number()<<endl;
                    break;
                default:
                    cout<<"Unkown ";
                    break;
                }
            }
            cout<<endl;
        }

  • 相关阅读:
    Linux中yum命令镜像源和出错解决方案
    Redis编译安装
    Linux下安装Redis
    zabbix3.4.2的安装及配置
    【前端】活动表单
    【笔记】archlinux缺少部分常用工具
    【笔记】BootstrapTable带参数刷新数据的坑
    【笔记】Win7连接公司内网无法打开网页
    【笔记】Archlinux下配置rsyslog写日志到mysql
    【笔记】Gave up waiting for suspend/resume device
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7347275.html
Copyright © 2011-2022 走看看