增强多对象序列化
boost serialization multiple objects
这个和这个有点关系
基本上,我想在对象来的时候序列化它们,就像日志文件一样,只是我想稍后对它们进行反序列化。这意味着我一开始没有所有的对象。
从之前的回答来看,如果一个人保持相同的存档打开,他可以继续向存档添加越来越多的对象。
但是我如何提取它们呢?我是否需要在每次拔牙前提前查看是否达到eof ?我是否应该在保存例程中放置换行符,以便以后可以逐行读取输入(这可能只适用于二进制文件(也可能适用于文本),因为xml使用换行符,如果二进制文件偶尔使用换行符,可能就不存在了)?也许>>操作抛出一个异常,如果到达文件结束,我可以包装它在一个无限循环与周围的尝试捕获?
如果我想对不同类型的对象这样做,我该怎么做呢?也许对所有对象都有一个枚举,并在之前序列化枚举,然后在反序列化时基于枚举进行切换?
谢谢
您所谈论的并不是序列化的真正意义。序列化被设计为在编译时确定写入和读取的顺序时工作。甚至版本控制也是编译时的;您可以根据运行时版本序列化值,也可以不序列化值。顺序保留。
现在,您可以向输出添加一些令牌,即映射到类类型的某种整数值。也就是说,在向流写入一个类之前,先写入一个表示该类的整数。然后稍后再读它,并根据它来决定下一步序列化什么类型。
但你将遇到的问题是,最终,你将耗尽内容。而连载档案并没有真正的方式说"这就是全部。"它们应该是编译时定义的,因此读取超过输入结束部分被认为是用户错误。因此,不容易支持处理任意数量的序列化数据。
同样,您可以在输出中写入一个特殊的标记,表示"这是结束"。
下面是我最后做的。既然Nicol是对的,而且这确实有点非预期的用途,那么首先必须确保禁用指针跟踪。否则就会得到虚假的共享对象。因此,从
的加载开始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) { }
这可能会捕获太多,所以可能需要一些额外的检查,但这对我来说是有效的。这样做的好处是适当的关闭并不是那么重要,例如,如果你的应用程序在中途崩溃,你仍然可以处理直到最后一个可读的消息。
我正在学习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::serialization::text_oarchive的大括号只有在我完成了逻辑结果的序列化后才会关闭。
- C++boost序列化多态性问题
- 序列化多晶型接口
- 从一个文件中读取多个序列化对象
- 初始化多对象双对象<矢量<矢量<float>> >
- 使用提升序列化多态类
- 手动提升序列化多映射
- 增强序列化多态性类
- 序列化 Protobuf 对象并使用 ØMQ/ZMQ 发送
- 如何使用boost::序列化将对象的矢量作为属性序列化对象
- 使用 boost::serialize (使用 SSCCE) 反序列化多个值
- 序列化多态类型的常见混淆
- xerces c 从刚刚序列化的对象创建对象的问题
- 增强序列化-启用对象跟踪
- 序列化多态指针的QVector
- 如何使用Boost序列化更新对象
- 如何序列化json对象,而不使用麦片将其封装在子对象中
- 预序列化消息对象-实现
- 使用mmap序列化复杂对象
- 工厂应该负责重新构造序列化的对象吗?
- (c++)从外部库序列化类对象