提升序列化文件结尾

时间:2011-07-12 14:24:58

标签: boost boost-serialization eof

我使用Boost将多个对象序列化为二进制存档。 从binary_iarchive读回这些对象时,有没有办法知道存档中有多少个对象,或者只是一种检测存档结束的方法?

我找到的唯一方法是使用try-catch来检测流异常。 提前谢谢。

4 个答案:

答案 0 :(得分:6)

我可以想到一些方法:

  1. 将STL容器序列化到您的存档中(参见documentation)。存档将自动跟踪容器中有多少个对象。

  2. 在序列化对象之前序列化计数变量。回读对象时,您事先会知道有多少对象需要回读。

  3. 您可以让最后一个对象具有一个特殊值,该值充当一种指示对象列表末尾的标记。也许您可以向对象添加isLast成员函数。

  4. 这不是很漂亮,但您可以在存档旁边放置一个单独的“索引文件”,用于存储存档中的对象数。

  5. 使用基础流对象的tellp位置来检测您是否位于文件末尾:

  6. 示例(仅草图,未经测试):

    std::streampos archiveOffset = stream.tellg(); 
    std::streampos streamEnd = stream.seekg(0, std::ios_base::end).tellg();
    stream.seekg(archiveOffset);
    
    while (stream.tellp() < streamEnd)
    {
        // Deserialize objects
    }
    

    这可能不适用于XML档案。

答案 1 :(得分:0)

开始序列化时,您是否拥有所有对象?如果没有,你正在“滥用”提升序列化 - 它并不意味着以这种方式使用。但是,我这样使用它,使用try catch来查找文件的结尾,它对我有用。只是将它隐藏在实现的某个地方。但要注意,如果以这种方式使用它,则需要不序列化指针或禁用指针跟踪。

如果您已经拥有所有物品,请参阅Emile的答案。它们都是有效的方法。

答案 2 :(得分:0)

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_);
  }
}

从档案中读取数据时使用zip,而filtering_streambuf具有

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

知道存档中最后有多少个对象不是帮助,而是帮助检测它们的结尾 (我仅在单元测试中使用eof测试来对我的类/结构进行序列化/反序列化-以确保我正在阅读所有自己编写的内容)

答案 3 :(得分:-1)

你刚从文件中读取一个字节。

如果你没有到达目的地,

然后

后退一个字节。

相关问题