2011-08-18 118 views
4

this onethis one有一點相關的問題。增強序列化多個對象

基本上,我想序列化它們來的對象,很像日誌文件,除了我想稍後反序列化它們。這意味着我最初沒有所有的對象。

從以前的答案看,如果一個人保持打開相同的存檔,可以繼續向存檔添加越來越多的對象。

但是,我會如何提取它們?我需要向前看,看看每次提取之前是否達到eof?我應該在保存程序中放置一個換行符,以便以後可以逐行讀取輸入內容(這可能只適用於二進制歸檔(也可能是文本),因爲xml使用換行符,甚至在二進制文件可能使用偶爾會有線路)?如果達到文件結尾,>>操作可能會引發異常,我可以用無限循環將它包裝起來,並試着抓住它?

如果我想爲不同種類的物體這樣做,我該怎麼辦?也許有一個enum的所有對象和序列化枚舉之前,並在unserializing有一個基於枚舉的開關?

謝謝

+0

相關:http://stackoverflow.com/questions/6665742/boost-serialization-end-of-file – maxschlepzig

回答

2

這是我最後做的。由於尼科爾是正確的,這實際上有點用處不大,首先必須確保禁用指針跟蹤。否則就會得到虛假的共享對象。因此,首先,中

BOOST_CLASS_TRACKING(yourDerivedClass,boost::serialization::track_never) 

負載我也落戶只是記錄,從相同的基礎對象派生的對象(你可以只爲此創建一個空的虛擬基)。一旦做到這一點,重要的是確保它被看作是抽象的是非常重要的(我確信有虛析構函數,並且創建後還增加

BOOST_SERIALIZATION_ASSUME_ABSTRACT(yourBaseClass) 

註冊所有派生類與存檔(包括寫和讀)

arMsgs.template register_type<yourDerivedClass>(); 

只註冊最終的非抽象類(如果A派生選自B選自C派生,不註冊B)。至少有任何已註冊的類需要已經跟蹤禁用。

最後將它們添加到歸檔中。

要重新加載它們,而不是使用文件結束一個特殊的記號,這需要檢查,我去

try 
{ 
    for(;;) 
    { 
     yourBaseClass obj; 
     arObjs >> boost::serialization::make_nvp("Obj",obj); 
     //your logic 
    } 
} 
catch(boost::archive::archive_exception const& e) { } 

這可能趕上有點太多,所以可能需要一些額外的檢查,但此正在爲我工​​作。優點是正確的關閉並不重要,例如,如果您的應用在中途崩潰,您仍然可以處理最後一條可讀消息。

2

你在說什麼不是真正的序列化點。序列化被設計爲在寫入和讀取的順序在編譯時間確定時工作。甚至版本編譯是編譯時間;您可以基於運行時版本序列化一個值或不是。訂單保留。

現在,你可能添加一些令牌到輸出,某種類型的映射到類類型的整數值。也就是說,在將類寫入流之前,需要編寫一個表示該類是什麼的整數。然後你再閱讀它,並根據它決定下一個序列化的類型。

但是你將遇到的問題是,最終你會用盡內容。而系列化檔案並沒有真正的方式來表達「這一切」。它們預計會被編譯時定義,所以讀取輸入結束時被認爲是用戶錯誤。因此處理任意數量的序列化數據並不容易。

再一次,你可以在輸出中寫一個特殊的標記,這個標記說:「這是結束。」

0

我正在學習boost,我認爲你可以使用boost序列化作爲日誌文件並使用你的邏輯繼續添加值。我面臨同樣的問題,如果我沒看錯你的代碼是這樣的:

#include <iostream> 
#include <fstream> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 

int main() { 
    int two=2; 

    for(int i=0;i<10;i++) { 

     std::ofstream ofs("table.txt"); 
     boost::archive::text_oarchive om(ofs); 
     om << two; 
     two = two+30; 
     std::cout<<"\n"<<two; 
    } 

    return 0; 
} 

這裏當您關閉括號(循環的大括號),序列化文件關閉。您可能會看到只寫在table.txt一個值,如果要存儲多個值,你的代碼應該是這樣的:

#include <iostream> 
#include <fstream> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/archive/text_oarchive.hpp> 

int main() { 
    int two=2; 

    { 
     std::ofstream ofs("table.txt"); 
     boost::archive::text_oarchive om(ofs); 
     for(int i=0;i<10;i++) { 

      om << two; 
      two = two+30; 
      std::cout<<"\n"<<two; 
     } 
    } 

    return 0; 
} 

在這裏你可以看到,在大括號包圍的boost ::系列化:: text_oarchive只有在我完成邏輯結果的序列化後纔會關閉。

+0

沒錯。或者只是讓文件流追加到循環中。 std :: ofstream ofs(「table.txt」,std :: ios :: app); –