Boost序列化结束文件
我使用Boost将多个对象序列化到二进制存档中。 当从Boost序列化结束文件,boost,boost-serialization,eof,Boost,Boost Serialization,Eof,我使用Boost将多个对象序列化到二进制存档中。 当从二进制文件中读回这些对象时,是否有办法知道归档文件中有多少对象,或者只是有办法检测归档文件的结尾 我发现的唯一方法是使用try-catch来检测流异常。 提前感谢。我可以想出一些方法: 序列化存档中的STL容器(请参阅)。存档将自动跟踪容器中有多少对象 在序列化对象之前序列化计数变量。在读回对象时,您将预先知道要读回多少对象 您可以让最后一个对象具有一个特殊值,该值充当一种指示对象列表结束的哨兵。也许您可以向对象添加isLast成员函数 这不
二进制文件
中读回这些对象时,是否有办法知道归档文件中有多少对象,或者只是有办法检测归档文件的结尾
我发现的唯一方法是使用try-catch来检测流异常。
提前感谢。我可以想出一些方法:
isLast
成员函数tellp
位置检测您是否在文件末尾:std::streampos archiveOffset=stream.tellg();
std::streampos streamEnd=stream.seekg(0,std::ios_base::end).tellg();
流。见千克(归档偏移);
while(stream.tellp()
这可能不适用于XML存档。您只需从文件中读取一个字节 如果你没有到达终点
一个字节的backword。当你开始序列化时,你有所有的对象吗?如果不是,那么您就是在“滥用”boost序列化—它不应该以这种方式使用。但是,我就是这样使用它的,使用
try-catch
查找文件的结尾,它对我很有用。只需将其隐藏在实现中的某个地方。但是要小心,如果以这种方式使用它,您需要要么不序列化指针,要么禁用指针跟踪
如果您已经拥有所有对象,请参见Emile的答案。这些都是有效的方法
std::istream* stream_;
boost::iostreams::filtering_streambuf<boost::iostreams::input>* filtering_streambuf_;
...
stream_ = new std::istream(memoryBuffer_);
if (stream_) {
filtering_streambuf_ = new boost::iostreams::filtering_streambuf<boost::iostreams::input>();
if (filtering_streambuf_) {
filtering_streambuf_->push(boost::iostreams::gzip_decompressor());
filtering_streambuf_->push(*stream_);
archive_ = new eos::portable_iarchive(*filtering_streambuf_);
}
}
因此,我将归档文件的结尾检查为
bool IArchiveContainer::eof() const {
if (filtering_streambuf_) {
return filtering_streambuf_->in_avail() == 0;
}
return false;
}
它并不能帮助您知道归档中最后有多少个对象,而是有助于检测它们的结束
(我只在单元测试中使用eof测试来序列化/非序列化我的类/结构-以确保我阅读了所有我正在编写的内容)谢谢你回答@Emile,容器确实很棒,唯一的问题是我的算法是随时都可以,即,它是迭代的,在迭代结束时,一些东西是序列化的。如果算法在某个点意外停止,我仍然可以从存档恢复运行:)哇。。。我第一次用一个如此简单的解决方案打自己的脚。上面的代码(#5)已损坏!(至少对于我的boost版本)如果创建归档,归档构造函数可能会在流中寻找一些非零偏移量。因此,后面的
stream.seekg(0)
在从存档读取时将产生错误,因为streampointer不在存档期望的位置@StackOverflow不是免费的代码传递服务。对提供的代码示例没有任何保证。使用它们的风险由您自己承担。我显然没有测试过这个例子;我提供它只是为了更好地解释OP问题的可能解决方案。话虽如此,我还是感谢您发现了错误并提出了改进建议。现在,其他人将从您的贡献中受益。:-)是的,我不是有意冒犯你的!我只是在没有检查的情况下拿走了你的代码。您提到它可能已损坏(对于xml)。那应该让我很难过。所以这真的是我的错:)如果使用try-catch是唯一对你有效的方法,那么你应该回答自己的问题,并接受自己的答案。在堆栈溢出中允许这样做(请参阅常见问题)。
std::streamsize std::streambuf::in_avail()
Get number of characters available to read
bool IArchiveContainer::eof() const {
if (filtering_streambuf_) {
return filtering_streambuf_->in_avail() == 0;
}
return false;
}