上一篇文章介紹了怎樣將數據序列化到了addressbook.data中,那麼對於接受方而言該怎麼解析出原本的數據呢。同樣,protoc編譯器生成的代碼文件中提供了反序列化的接口,基本上和序列化的函數對應的,如下圖所示:
上文中採用了SerializeToOstream、SerializeToString、SerializeToCodedStream來序列化數據的,反序列化反其道行之即可。本文反序列化採用ParseFromArray方式,從某個角度算是對上文的一個補充吧!
反序列化也是分爲兩個步驟:
1)將數據載入內存或者輸入流
2)調用庫提供的反序列化接口函數進行反序列化
一、將數據載入
將數據從文件中讀出時候,需要注意以二進制的模式打開,且編碼格式要指定正確,如下所示:
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.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;
}
運行結果如下所示:
好了,相信通過本系列文章,讀者應該對Google Protocol Buffer有一定的認識了吧。當然,想要更深入的瞭解,還是參考Google的官方在線文檔吧!
示例代碼下載地址:SerialProtocolBuffer示例代碼
歡迎轉載,轉載時請務必保留原文出處:http://www.cnblogs.com/royenhome ,謝謝合作!