2011-08-18 66 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); –