C++ Boost 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

我正在使用Boost将类的实例序列化为XML文件。该类包含一个我希望保存到单独的二进制(或ASCII)文件中的集合。理想情况下(但不是强制性的),我希望XML包含该单独文件的路径。然后,在我的主脚本中,我调用静态
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