将 boost::serialization::serialize'ble 结构作为二进制文件存储到硬盘上

Store a boost::serialization::serialize'ble struct as binary onto harddisk

我想将下面的示例作为简单的二进制文件存储到硬盘上。但是在网上我还没有找到任何简单明了的例子如何做到这一点,所以我在质疑:

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

#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. 需要 return example 中的 make_example()。您可能会在此处收到您忽略的编译器警告。
  2. 需要#include <boost/archive/binary_oarchive.hpp>。否则,它甚至不应该编译。

此外,您的评论 // 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 的 SO 回答。然后您需要:

  1. 将您的 serialize 函数拆分为单独的 loadsave 函数。有关示例,请参见 this(在 Tutorial::Splitting 下序列化为 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>,您不再需要它。

这应该使二进制存档中每个 std::bitset<N> 的存储从 N(N+7)/8 字节。

希望这对您有所帮助。