将 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
}
我认为问题是:
- 需要 return
example
中的 make_example()
。您可能会在此处收到您忽略的编译器警告。
- 需要
#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 回答。然后您需要:
- 将您的
serialize
函数拆分为单独的 load
和 save
函数。有关示例,请参见 this(在 Tutorial::Splitting 下序列化为 save/load)。
- 在
save
中,迭代e.bits
并使用@6502的bitset_to_bytes
函数将e.bits[i]
的EACH转换为一个std::vector<unsigned char>
。然后您将拥有一个 std::vector<std::vector<unsigned char>>
(save
函数中的局部变量)。序列化那个。
- 相反,在
load
中,反序列化得到一个 std::vector<std::vector<unsigned char>>
(同样,load
中的局部变量)。然后,迭代该集合并使用@6502 的 bitset_from_bytes<N>
函数将 EACH std::vector<unsigned char>
转换为 e.bits[i]
.
- 删除
#include <boost/serialization/bitset.hpp>
,您不再需要它。
这应该使二进制存档中每个 std::bitset<N>
的存储从 N
到 (N+7)/8
字节。
希望这对您有所帮助。
我想将下面的示例作为简单的二进制文件存储到硬盘上。但是在网上我还没有找到任何简单明了的例子如何做到这一点,所以我在质疑:
如何修改下面的代码以将结构作为二进制文件存储在二进制文件中?
#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
}
我认为问题是:
- 需要 return
example
中的make_example()
。您可能会在此处收到您忽略的编译器警告。 - 需要
#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 回答。然后您需要:
- 将您的
serialize
函数拆分为单独的load
和save
函数。有关示例,请参见 this(在 Tutorial::Splitting 下序列化为 save/load)。 - 在
save
中,迭代e.bits
并使用@6502的bitset_to_bytes
函数将e.bits[i]
的EACH转换为一个std::vector<unsigned char>
。然后您将拥有一个std::vector<std::vector<unsigned char>>
(save
函数中的局部变量)。序列化那个。 - 相反,在
load
中,反序列化得到一个std::vector<std::vector<unsigned char>>
(同样,load
中的局部变量)。然后,迭代该集合并使用@6502 的bitset_from_bytes<N>
函数将 EACHstd::vector<unsigned char>
转换为e.bits[i]
. - 删除
#include <boost/serialization/bitset.hpp>
,您不再需要它。
这应该使二进制存档中每个 std::bitset<N>
的存储从 N
到 (N+7)/8
字节。
希望这对您有所帮助。