将boost :: serialization :: serialize&#ble; ble struct作为二进制文件存储到硬盘上

时间:2016-07-21 12:18:38

标签: c++ serialization boost boost-serialization

我想将下面的示例存储到硬盘上作为一个简单的二进制文件。但是在网络上我找不到任何简单而干净的例子,所以我在质疑:

如何修改下面的代码将结构作为二进制文件存储在二进制文件中?

#include <vector>
#include <string>
#include <bitset>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/bitset.hpp>

template<size_t N>
struct Example
{
  std::string id;
  std::vector<std::bitset<N>> bits;
};

template<size_t N>
Example<N> make_example()
{
  Example<N> example;

  example.id = "some id";

  example.bits.resize(100);
}

namespace boost
{
  namespace serialization
  {
    template<typename Archive, size_t N>
    void serialize ( Archive & a
                   , Example<N> & e
                   , const unsigned int version )
    {
        a & e.id;
        a & e.bits;
    }
  }
}

int main()
{
  auto example = make_example<256>();

  std::ofstream ofs("filename", std::ios::binary);

  boost::archive::binary_oarchive oa(ofs);

  oa << example; // shouldn't use << as oa writes a text archive
}

1 个答案:

答案 0 :(得分:3)

我认为问题是:

  1. 需要返回example中的make_example()。你可能在这里得到了一个你忽略的编译器警告。
  2. 需要#include <boost/archive/binary_oarchive.hpp>。否则,它甚至不应该编译。
  3. 此外,您的评论// shouldn't use << as oa writes a text archive不太正确,因为<<现在已为boost::archive::binary_oarchive重载,因此它是流二进制文件。

    因此,修改后的代码应如下所示:

    #include <vector>
    #include <string>
    #include <bitset>
    #include <fstream>
    #include <boost/serialization/string.hpp>
    #include <boost/serialization/vector.hpp>
    #include <boost/serialization/bitset.hpp>
    // ADD THIS!!!
    #include <boost/archive/binary_oarchive.hpp>
    
    template<size_t N>
    struct Example
    {
      std::string id;
      std::vector<std::bitset<N>> bits;
    };
    
    template<size_t N>
    Example<N> make_example()
    {
      Example<N> example;
    
      example.id = "some id";
    
      example.bits.resize(100);
      // ADD THIS!!!
      return(example);
    }
    
    namespace boost
    {
      namespace serialization
      {
        template<typename Archive, size_t N>
        void serialize ( Archive & a
                       , Example<N> & e
                       , const unsigned int version )
        {
            a & e.id;
            a & e.bits;
        }
      }
    }
    
    int main()
    {
      auto example = make_example<256>();
    
      std::ofstream ofs("filename", std::ios::binary);
    
      boost::archive::binary_oarchive oa(ofs);
    
      oa << example;
    
      return(0);
    }
    

    关于SO的相关示例是here

    更新使std::bitset的二进制序列化更紧凑

    请查看@ 6502 here的答案。然后你需要:

    1. 将您的serialize功能拆分为单独的loadsave功能。有关示例,请参阅this(在Tutorial :: Splitting serialize into save / load中)。
    2. save中,迭代e.bits并使用@ 6502的bitset_to_bytes函数将e.bits[i] EACH 转换为std::vector<unsigned char> }。然后,您将拥有std::vector<std::vector<unsigned char>>save函数中的局部变量)。序列化。
    3. 相反,在load中,反序列化以获取std::vector<std::vector<unsigned char>>(同样,load中的局部变量)。然后,迭代该集合并使用@ 6502的bitset_from_bytes<N>函数将 EACH std::vector<unsigned char>转换为e.bits[i]
    4. 删除#include <boost/serialization/bitset.hpp>,您不再需要它。
    5. 这应该会将每个std::bitset<N>的存储空间从N转换为(N+7)/8个字节。

      希望这有帮助。