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

使用Boost序列化并压缩std::map时反序列化出现输入流错误的问题排查及调试方法

使用Boost序列化并压缩std::map时反序列化出现输入流错误的问题排查及调试方法

嗨,我帮你看了下代码,问题其实出在反序列化的一个小细节上,很容易疏忽!

直接问题:反序列化时用错了流对象

你在反序列化代码里创建binary_iarchive的时候,传入的是原始的文件流f,但实际上应该传入经过gzip解压处理的过滤流filter!

错误的代码行:

boost::archive::binary_iarchive ar(f);

正确的写法应该是:

boost::archive::binary_iarchive ar(filter);

为什么会报错呢?因为你序列化的时候,是把数据写入了带有gzip压缩的过滤流,最终文件里存的是压缩后的二进制数据。反序列化时如果直接给归档器传原始文件流,它读到的是压缩后的乱码数据,完全不符合Boost归档的格式,自然就抛出了「输入流错误」的异常。

修正后的完整反序列化代码

#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <map>
#include <vector>

int main() {
    std::map<uint64_t, std::vector<uint64_t>> m;
    std::ifstream f("test_archive.gz", std::ios::binary);
    if(f.fail()) {
        std::cerr << "Couldn't open the archive\n";
        return 1; // 记得加返回值,避免后续错误执行
    }

    boost::iostreams::filtering_istream filter;
    filter.push(boost::iostreams::gzip_decompressor());
    filter.push(f);

    // 这里改成传入filter,而不是f
    boost::archive::binary_iarchive ar(filter);
    ar >> m;

    for(const auto& [key, value] : m) {
        std::cout << key << " -> " << "[";
        bool first = true;
        for(const auto& e: value) {
            if(!first) std::cout << ", ";
            std::cout << e;
            first = false;
        }
        std::cout << "]\n";
    }
    return 0;
}

(我还顺手给你加了返回值和处理输出逗号的小优化,避免输出[100, 200, 300, 400, ]这种带尾逗号的格式)

后续调试方法(遇到类似问题时用)

如果以后再遇到这类流或者归档的问题,可以用这些方法分步排查:

  • 分步隔离测试:先去掉gzip压缩逻辑,直接序列化到普通二进制文件,反序列化也直接读原始文件,确认纯Boost序列化的逻辑没问题,再加上压缩过滤流,这样能快速定位是序列化本身还是压缩流的问题。
  • 验证压缩文件完整性:用系统的gzip -d test_archive.gz命令解压文件,如果解压失败,说明序列化时的压缩过程出了问题;如果解压成功,得到的二进制文件可以用Boost的纯二进制归档反序列化测试,确认数据格式正确。
  • 捕获并细化异常信息:给反序列化代码加try-catch,捕获boost::archive::archive_exception,打印更详细的错误码,能帮你更快定位问题类型:
try {
    boost::archive::binary_iarchive ar(filter);
    ar >> m;
} catch (const boost::archive::archive_exception& e) {
    std::cerr << "归档异常详情:" << e.what() << ",错误码:" << e.code << std::endl;
}
  • 检查流的状态:在每次操作流之后(比如打开文件、创建过滤流、读取数据后),都检查流的good()或者fail()状态,提前发现流的问题,比如文件没打开、过滤流初始化失败等。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:48:07