介绍下怎么反序列化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!\n"<<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!\n";

        return;

    }

    memset(buffer,'\0',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!\n";

        return;

    }





    int personSize = addressBook.person_size();





    for( int i=0 ;i<personSize; i++ )

    {

        Person p = addressBook.person( i );

        cout<<"Person "<<i+1<<":\nid\t"<<p.id()<<"\nname:\t"<<p.name()<<"\n";

        int phoneSize = p.phone_size();

        for( int j=0;j<phoneSize;j++ )

        {

            Person_PhoneNumber phone = p.phone(j);

            cout<<"Phone "<<j+1<<":\nType:\t";

            switch( phone.type())

            {

            case Person_PhoneType_MOBILE:

                cout<<"Mobile\t\tPhone Number:\t"<<phone.number()<<endl;

                break;

            case Person_PhoneType_HOME:

                cout<<"Home\t\tPhone Number:\t"<<phone.number()<<endl;

                break;

            case Person_PhoneType_WORK:

                cout<<"Work\t\tPhone Number:\t"<<phone.number()<<endl;

                break;

            default:

                cout<<"Unkown\n";

                break;

            }

        }

        cout<<endl;

    }

最新文章

  1. css3 风车旋转
  2. SQL一次查出多个字段的COUNT值
  3. java多线程-CyclicBarrier
  4. 12/09 Oracle练习之新建表
  5. Spring学习笔记之BeanFactory
  6. Tcl之load
  7. I.MX6 build.prop
  8. thinkphp验证码的实现
  9. Substring的简单使用
  10. JAR WAR EAR包的区别
  11. hihoCoder 1116 计算 (线段树)
  12. click延时300ms的故事
  13. Linux下protobuf的编译与安装【各种奇葩问题】
  14. 谈谈单元測试之(二):測试工具 JUnit 3
  15. angular自定义分页组件(实用)
  16. 【Java入门提高篇】Day14 Java中的泛型初探
  17. arcgis api 3.x for js 入门开发系列二十一气泡窗口信息动态配置模板
  18. C#事件の.net下的EventArgs和EventHandler
  19. C++ GetUserName()
  20. 【Core】在mvc使用EF

热门文章

  1. ubuntu环境下android开发环境安装
  2. Java从零开始学二十(集合简介)
  3. android设备上运行i-jetty服务
  4. STS 自动生成 getter 和 setter
  5. Flash builder 调试技巧 (分享)
  6. [Done]SnowFlake 分布式环境下基于ZK构WorkId
  7. java Properties的用法
  8. 拯救者14ISK添加ssd6记录
  9. 原生php如何获取当前页面的url
  10. TP3.2:实现Ajax无刷新上传图片