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

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

本文关键字:二进制文件 存储 硬盘 结构 ble serialization boost serialize      更新时间:2023-10-16

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

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

#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. 需要在make_example()中返回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的相关示例。


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

看看@6502的SO答案。然后您需要:

  1. serialize函数拆分为单独的loadsave函数。有关示例,请参见此(在教程::将序列化拆分为保存/加载下)
  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>函数将EACHstd::vector<unsigned char>转换为e.bits[i]
  4. 移除#include <boost/serialization/bitset.hpp>,您不再需要它

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

希望这能有所帮助。