C++ Boost XML序列化在单独的二进制文件中保存集合
我正在使用Boost将类的实例序列化为XML文件。该类包含一个我希望保存到单独的二进制(或ASCII)文件中的集合。理想情况下(但不是强制性的),我希望XML包含该单独文件的路径。然后,在我的主脚本中,我调用静态C++ Boost XML序列化在单独的二进制文件中保存集合,c++,xml,serialization,boost,binary,C++,Xml,Serialization,Boost,Binary,我正在使用Boost将类的实例序列化为XML文件。该类包含一个我希望保存到单独的二进制(或ASCII)文件中的集合。理想情况下(但不是强制性的),我希望XML包含该单独文件的路径。然后,在我的主脚本中,我调用静态Save方法来序列化实例,然后调用Load方法来反序列化实例 下面是我想做的一个例子: class MyClass { public: ... friend class boost::serialization::access; template&l
Save
方法来序列化实例,然后调用Load
方法来反序列化实例
下面是我想做的一个例子:
class MyClass
{
public:
...
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(a);
ar & <EXT_BINARY_FILE>(c);
}
static void Save(const MyClass& inst, const std::string& filename)
{
std::ofstream ofs(filename);
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(input);
}
static void Load(MyClass& inst, const std::string& filename)
{
std::ifstream ifs(filename);
boost::archive::xml_iarchive ia(ifs);
ia >> BOOST_SERIALIZATION_NVP(input);
}
private:
int a;
std::vector<int> b;
};
class-MyClass
{
公众:
...
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&BOOST_序列化_NVP(a);
应收账款和(c);
}
静态void保存(常量MyClass&inst,常量std::string&filename)
{
std::ofs流(文件名);
boost::archive::xml_oarchive oa(ofs);
oa>BOOST\U序列化\U NVP(输入);
}
私人:
INTA;
std::载体b;
};
在文件系统中,我将获得以下文件树:
- myclass.xml
- c、 dat
您知道如何执行此操作吗?当然知道。正确的方法是实现您自己的归档类型。这可能涉及其中,我对此没有经验 因此,您可能可以使用一个有一些限制的
- 我没有使de tag name可配置
- 您可能希望插入一个目标目录以包含生成的二进制归档文件。现在,它只是假设当前的工作目录是有意义的
- 嵌套对象的对象跟踪不在窗口中:因为您每次都将包装好的对象写入新存档,所以该存档的跟踪始终是第一次看到对象
namespace uuids = boost::uuids;
template <typename T>
struct ExtBinaryFile {
using base = boost::serialization::nvp<T>;
ExtBinaryFile(T& ref) : ref_(ref) {}
private:
T& ref_;
friend boost::serialization::access;
template <typename Ar> void save(Ar& ar, unsigned) const {
auto src = random_name();
{
std::ofstream ofs(src, std::ios::binary);
boost::archive::binary_oarchive boa(ofs);
boa << ref_;
}
ar & BOOST_SERIALIZATION_NVP(src);
}
template <typename Ar> void load(Ar& ar, unsigned) {
std::string src;
ar & BOOST_SERIALIZATION_NVP(src);
{
std::ifstream ifs(src, std::ios::binary);
boost::archive::binary_iarchive bia(ifs);
bia >> ref_;
}
}
template <typename Ar> void serialize(Ar& ar, unsigned version) {
boost::serialization::split_member(ar, *this, version);
//if constexpr(Ar::is_saving::value) {
//this->save(ar, version);
//} else {
//this->load(ar, version);
//}
}
static std::string random_name() {
std::ostringstream oss;
std::mt19937 prng(std::random_device{}());
uuids::basic_random_generator<std::mt19937> gen{prng};
oss << gen() << ".dat";
return oss.str();
}
};
在那里。现在,我们并不意外地认为包装器的标识很重要
演示
here.xml
:
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
名称空间uuids=boost::uuids;
模板
结构ExtBinaryFile{
使用base=boost::serialization::nvp;
ExtBinaryFile(T&ref):ref_u2;(ref){}
私人:
T&ref;
friend boost::serialization::access;
模板无效保存(应收和应收,未签名)常量{
auto src=random_name();
{
ofs流的std::of(src,std::ios::binary);
boost::archive::binary_oarchive boa(ofs);
boa>参考;
}
}
模板无效序列化(Ar&Ar,未签名版本){
boost::serialization::split_成员(ar,*此,版本);
//如果constexpr(Ar::is_saving::value){
//此->保存(ar,版本);
//}否则{
//此->加载(ar,版本);
//}
}
静态标准::字符串随机_名称(){
std::ostringstream oss;
std::mt19937 prng(std::random_设备{}());
uuids::基本随机发生器gen{prng};
开放源码软件
namespace boost { namespace serialization {
template <typename T> struct is_wrapper<ExtBinaryFile<T> > : std::true_type {};
template <typename T> struct tracking_level<ExtBinaryFile<T> > {
static const tracking_type value = tracking_type::track_never;
};
// const versions for completeness
template <typename T> struct is_wrapper<const ExtBinaryFile<T> > : is_wrapper<ExtBinaryFile<T> > {};
template <typename T> struct tracking_level<const ExtBinaryFile<T> > : tracking_level<ExtBinaryFile<T> > {};
} }
class MyClass {
public:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, unsigned) {
auto dat = make_ext_binary(b);
ar & BOOST_SERIALIZATION_NVP(a)
& BOOST_SERIALIZATION_NVP(dat)
;
}
static void Save(const MyClass& inst, const std::string& filename) {
std::ofstream ofs(filename);
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(inst);
}
static void Load(MyClass& inst, const std::string& filename) {
std::ifstream ifs(filename);
boost::archive::xml_iarchive ia(ifs);
ia >> BOOST_SERIALIZATION_NVP(inst);
}
//private:
int a = 0;
std::vector<int> b;
};
int main() {
{
MyClass orig;
orig.a = 99;
std::generate_n(back_inserter(orig.b), 1024, ::rand);
MyClass::Save(orig, "here.xml");
}
{
MyClass roundtrip;
MyClass::Load(roundtrip, "here.xml");
std::cout << "a: " << roundtrip.a << " b:" << roundtrip.b.size() << " elements\n";
}
}
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp -lboost_serialization
./a.out; ls -ltrah here.xml *.dat
a: 99 b:1024 elements
-rw-r--r-- 1 2001 2000 365 Jun 9 18:03 here.xml
-rw-r--r-- 1 2001 2000 4.1K Jun 9 18:03 55a89355-2637-42e4-b285-9846b046485e.dat