Boost序列化结束文件

Boost序列化结束文件,boost,boost-serialization,eof,Boost,Boost Serialization,Eof,我使用Boost将多个对象序列化到二进制存档中。 当从二进制文件中读回这些对象时,是否有办法知道归档文件中有多少对象,或者只是有办法检测归档文件的结尾 我发现的唯一方法是使用try-catch来检测流异常。 提前感谢。我可以想出一些方法: 序列化存档中的STL容器(请参阅)。存档将自动跟踪容器中有多少对象 在序列化对象之前序列化计数变量。在读回对象时,您将预先知道要读回多少对象 您可以让最后一个对象具有一个特殊值,该值充当一种指示对象列表结束的哨兵。也许您可以向对象添加isLast成员函数 这不

我使用Boost将多个对象序列化到二进制存档中。 当从
二进制文件
中读回这些对象时,是否有办法知道归档文件中有多少对象,或者只是有办法检测归档文件的结尾

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

我可以想出一些方法:

  • 序列化存档中的STL容器(请参阅)。存档将自动跟踪容器中有多少对象

  • 在序列化对象之前序列化计数变量。在读回对象时,您将预先知道要读回多少对象

  • 您可以让最后一个对象具有一个特殊值,该值充当一种指示对象列表结束的哨兵。也许您可以向对象添加
    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;
    }