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!\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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章