乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Google Protocol Buffers淺析(三)

       feng0926 2013-08-06

           本文主要會介紹怎么使用Google Protocol的Lib來序列化我們的數(shù)據(jù),方法很多種,本文只介紹其中的三種,其他的方法讀者可以通過自行研究摸索。但總的來說,序列化數(shù)據(jù)總的來說分為以下倆步:

           1)使用數(shù)據(jù)源填充數(shù)據(jù)結(jié)構(gòu),無論數(shù)據(jù)源來自文件還是內(nèi)存還是標(biāo)準(zhǔn)輸入

           2)利用Lib提供的序列化接口將數(shù)據(jù)結(jié)構(gòu)序列化,然后存儲在內(nèi)存或者磁盤上

          

           一、填充數(shù)據(jù)結(jié)構(gòu) 

           從數(shù)據(jù)源中獲取數(shù)據(jù),這兒的數(shù)據(jù)源可能來自磁盤上的一個文件或者內(nèi)存中存儲的一段數(shù)據(jù)或者來自標(biāo)準(zhǔn)輸入的數(shù)據(jù)。我們需要做的就是,將AddressBook這個數(shù)據(jù)結(jié)構(gòu)中的各個字段填充。本例中是通過AddressBook提供的add_person函數(shù)來獲得一個Person的指針,從而對其進行填充,如下代碼所示: 

      復(fù)制代碼
          //地址簿數(shù)據(jù)定義
          AddressBook    addressBook;            
          
          
      //第一個聯(lián)系人的數(shù)據(jù)定義與初始化
          Person    *personMe  = addressBook.add_person();
          personMe
      ->set_id(1);
          personMe
      ->set_name("royen");    
          personMe
      ->set_email("zwg19891129@163.com");
          personMe
      ->set_unsure("19bf173a0e87ab");
          
          
      //第二個聯(lián)系人的數(shù)據(jù)定義與初始化
          Person  *personHim = addressBook.add_person();
          personHim
      ->set_id(2);
          personHim
      ->set_name("XXX");
          personHim
      ->set_email("XXX@XXX.com");
          personHim
      ->set_unsure("19bf173a0e87ab");
          
          
      //personMe的手機號碼數(shù)據(jù)定義與初始化
          Person_PhoneNumber *phoneNumberMobile = personMe->add_phone();
          phoneNumberMobile
      ->set_number("15996110120");
          phoneNumberMobile
      ->set_type(Person_PhoneType_MOBILE);
              
          
      //personMe的座機號碼數(shù)據(jù)定義與初始化
          Person_PhoneNumber *phoneNumberHome   = personMe->add_phone();
          phoneNumberHome
      ->set_number("0256110120");
          phoneNumberHome
      ->set_type(Person_PhoneType_HOME);

          
      //personHim的一個號碼數(shù)據(jù)定義與初始化
          Person_PhoneNumber *phoneNumberHim      = personHim->add_phone();
          phoneNumberHim
      ->set_number("15996111111");    
          phoneNumberHim
      ->set_type(Person_PhoneType_HOME);
      復(fù)制代碼

               很容易看出,上述代碼即在地址簿中添加了倆個聯(lián)系人,然后又分別填充各個聯(lián)系人的數(shù)據(jù)信息,通過上述代碼一個地址簿的數(shù)據(jù)便準(zhǔn)備好了。

              

              二、序列化數(shù)據(jù) 

              其實通過看編譯器生成的AddressBook這個類所提供的方法名,既可以大致知道有哪些序列化的方式,如下所示:

               

              從上圖可以看出,可利用序列化的方法很多,本文中主要使用SerializeToString、SerializeToCodedStream以及SerializeToOstream來完成序列化。 

              下面就分別就這幾種方式來介紹下:

              1) SerializeToCodedStream方式

              首先可以知道該函數(shù)的原型是bool SerializeToCodedStream(std::ostream *),所以使用該函數(shù)需要結(jié)合C++的fstream流,代碼如下:         

      復(fù)制代碼
          //方法一: 使用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();
      復(fù)制代碼

                可以看出,采用這種方法相當(dāng)?shù)谋憬?,而且也很簡潔,但有個缺點就是輸出到文件的編碼格式不好控制,所以可以使用下面介紹的這種方法。

               

             2)SerializeToString方式

             函數(shù)原型為bool SerializeToString(std::string* output) ,所以可以講填充在數(shù)據(jù)結(jié)構(gòu)AddressBook中的數(shù)據(jù)取出存到一個string對象中,然后再以二進制流的方式將其寫入到磁盤文件中,代碼如下:               

      復(fù)制代碼
          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;
          }
       
      復(fù)制代碼

             上述代碼稍微繁瑣了點,但是也是一種序列化的方式,通過結(jié)合使用C庫中的文件操作函數(shù),可以更方便的定制輸出文件。

        

             3)SerializeToCodedStream方式

             該方式主要指用到的google buffer的庫中提供的一組數(shù)據(jù)流操作對象,在使用這些對象之前需要引入一些頭文件,如下所示:       

         #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;

             該方式也結(jié)合C庫的open與write函數(shù),序列化部分的代碼如下:               

      復(fù)制代碼
          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);    
      復(fù)制代碼

              本文暫時介紹這三種序列化話方式,還有像SerializeToArray以及SerializeToFileDescriptor等方式都應(yīng)該比較類似,所以感興趣的朋友可以自己動手試試。   

              下篇文章再稍微介紹下反序列化的方法,但是應(yīng)該不會太多內(nèi)容,畢竟都方法都很相似。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多