You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Boost XML序列化将类集合保存至独立二进制文件?

实现Boost序列化中集合的外部文件存储

要实现你想要的「将集合单独保存到二进制文件,XML中存储该文件路径」的需求,Boost序列化本身没有内置的<EXT_BINARY_FILE>操作,但我们可以通过扩展序列化逻辑手动实现这个功能。核心思路是区分XML归档类型,在序列化时将集合写入外部文件并记录路径,反序列化时读取路径并加载外部文件内容。

以下是完整的实现方案:

1. 修改类结构与序列化逻辑

首先给MyClass添加一个存储外部二进制文件路径的成员(用mutable修饰,方便在const上下文中修改),然后扩展serialize模板函数,添加外部文件的读写逻辑:

#include <boost/serialization/serialization.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/is_xml_archive.hpp>
#include <boost/serialization/vector.hpp>
#include <filesystem>
#include <fstream>
#include <string>
#include <stdexcept>

namespace fs = std::filesystem;

class MyClass {
public:
    static void Save(const MyClass& inst, const std::string& filename);
    static void Load(MyClass& inst, const std::string& filename);

private:
    int a = 0;
    std::vector<int> b;
    mutable std::string m_binary_path; // 存储外部二进制文件路径

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive& ar, const unsigned int version) {
        // 序列化普通成员a
        ar & BOOST_SERIALIZATION_NVP(a);

        const bool is_xml = boost::serialization::is_xml_archive<Archive>::value;
        std::string binary_path;

        if constexpr (boost::serialization::is_saving<Archive>::value) {
            binary_path = m_binary_path;
            // 仅XML归档时,将集合写入外部二进制文件
            if (is_xml && !binary_path.empty()) {
                std::ofstream bin_file(binary_path, std::ios::binary);
                if (!bin_file.is_open()) {
                    throw std::runtime_error("无法打开二进制文件进行写入: " + binary_path);
                }
                boost::archive::binary_oarchive bin_ar(bin_file);
                bin_ar & b; // 将集合b序列化到二进制文件
            }
            // 把二进制文件路径存入XML归档
            ar & BOOST_SERIALIZATION_NVP(binary_path);
        } else {
            // 加载时先读取二进制文件路径
            ar & BOOST_SERIALIZATION_NVP(binary_path);
            if (is_xml && !binary_path.empty()) {
                std::ifstream bin_file(binary_path, std::ios::binary);
                if (!bin_file.is_open()) {
                    throw std::runtime_error("无法打开二进制文件进行读取: " + binary_path);
                }
                boost::archive::binary_iarchive bin_ar(bin_file);
                bin_ar & b; // 从二进制文件反序列化集合b
            } else {
                // 非XML归档时直接序列化集合(兼容其他归档类型)
                ar & BOOST_SERIALIZATION_NVP(b);
            }
        }
    }
};

2. 实现Save和Load静态方法

在Save方法中,我们根据XML文件路径生成对应的二进制文件路径(比如同目录下的c.dat),设置到类成员后再执行XML序列化:

void MyClass::Save(const MyClass& inst, const std::string& filename) {
    MyClass temp_inst = inst;
    fs::path xml_path(filename);
    // 生成二进制文件路径:与XML文件同目录,文件名为c.dat
    temp_inst.m_binary_path = (xml_path.parent_path() / "c.dat").string();

    std::ofstream xml_file(filename);
    if (!xml_file.is_open()) {
        throw std::runtime_error("无法打开XML文件进行写入: " + filename);
    }
    boost::archive::xml_oarchive xml_ar(xml_file);
    xml_ar << BOOST_SERIALIZATION_NVP(temp_inst);
}

void MyClass::Load(MyClass& inst, const std::string& filename) {
    std::ifstream xml_file(filename);
    if (!xml_file.is_open()) {
        throw std::runtime_error("无法打开XML文件进行读取: " + filename);
    }
    boost::archive::xml_iarchive xml_ar(xml_file);
    xml_ar >> BOOST_SERIALIZATION_NVP(inst);
}

3. 关键逻辑说明

  • 归档类型判断:通过boost::serialization::is_xml_archive区分当前是否为XML归档,仅在XML归档时处理外部文件,同时兼容其他归档类型(比如直接二进制归档)。
  • 路径处理:用std::filesystem(C++17及以上)管理文件路径,确保二进制文件与XML文件处于同一目录,避免路径混乱。
  • 异常处理:添加了文件打开失败的异常抛出,方便调试和错误捕获(你可以根据需求调整为返回错误码等方式)。
  • 灵活性:如果需要自定义二进制文件名,只需修改Save方法中生成路径的逻辑,比如基于XML文件名生成唯一的二进制文件名(如myclass_c.dat)。

最终生成的文件结构

执行Save方法后,会在XML文件所在目录生成两个文件:

  • myclass.xml:包含a的值和binary_path(即c.dat的相对路径)
  • c.dat:存储std::vector<int> b的二进制序列化数据

内容的提问来源于stack exchange,提问作者Eric David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:43:01