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

Boost gzip_compressor压缩流读写异常:读取uint64_t获坏字节

压缩数据读写异常问题分析

代码实现

以下是使用Boost.Iostreams实现的压缩数据保存与加载函数:

namespace io = boost::iostreams;    

void saveCompressedData(const std::string& file_path, const std::vector<double>& bid, const std::vector<double>& ask, const std::vector<double>& close_prices, const std::vector<int>& tick_numbers) {
        try {
            // Create an output file stream and filtering stream
            std::ofstream file(file_path, std::ios_base::out | std::ios_base::binary);
            if (!file) {
                std::cerr << "Error opening compressed file for writing: " << file_path << std::endl;
                return;
            }
    
            io::filtering_ostream out;
            out.push(io::gzip_compressor());
            out.push(file);
    
            // Write the data to the compressed file
            uint64_t size = bid.size();
            out.write((const char* ) (&size), sizeof(size));
            out.write(reinterpret_cast<const char*>(bid.data()), size * sizeof(double));
            out.write(reinterpret_cast<const char*>(ask.data()), size * sizeof(double));
    
            size_t close_size = close_prices.size();
            out.write(reinterpret_cast<const char*>(&close_size), sizeof(close_size));
            out.write(reinterpret_cast<const char*>(close_prices.data()), close_size * sizeof(double));
    
            size_t tick_size = tick_numbers.size();
            out.write(reinterpret_cast<const char*>(&tick_size), sizeof(tick_size));
            out.write(reinterpret_cast<const char*>(tick_numbers.data()), tick_size * sizeof(int));
            out.pop();
    
        }
        catch (const std::exception& e) {
            std::cerr << "Exception while writing compressed data: " << e.what() << std::endl;
        }
    }
    
    void loadCompressedData(const std::string& file_path, std::vector<double>& bid, std::vector<double>& ask, std::vector<double>& close_prices, std::vector<int>& tick_numbers) {
        try {
            // Create an input file stream and filtering stream
            std::ifstream file(file_path, std::ios_base::in | std::ios_base::binary);
            if (!file) {
                std::cerr << "Error opening compressed file for reading: " << file_path << std::endl;
                return;
            }
    
            io::filtering_istream in;
            in.push(io::gzip_decompressor());
            in.push(file);
    
            // Read the data from the compressed file
            uint64_t size;
            in.read((char*)(&size), sizeof(size));
            bid.resize(size);
            ask.resize(size);
            in.read(reinterpret_cast<char*>(bid.data()), size * sizeof(double));
            in.read(reinterpret_cast<char*>(ask.data()), size * sizeof(double));
    
            size_t close_size;
            in.read(reinterpret_cast<char*>(&close_size), sizeof(close_size));
            close_prices.resize(close_size);
            in.read(reinterpret_cast<char*>(close_prices.data()), close_size * sizeof(double));
    
            size_t tick_size;
            in.read(reinterpret_cast<char*>(&tick_size), sizeof(tick_size));
            tick_numbers.resize(tick_size);
            in.read(reinterpret_cast<char*>(tick_numbers.data()), tick_size * sizeof(int));
    
        }
        catch (const std::exception& e) {
            std::cerr << "Exception while reading compressed data: " << e.what() << std::endl;
        }
    }

问题描述

测试上述代码时,在loadCompressedData函数中读取uint64_t类型的size变量时获取到错误字节,请问可能的原因是什么?

可能的原因分析

  • 字节序(端序)不匹配:直接将内存中的二进制数据写入文件时,不同CPU架构的字节序(小端/大端)会导致数值解析错误。比如在x86(小端)机器写入的uint64_t数据,在大端架构的机器上读取时,字节顺序会被反转,得到完全错误的数值。
  • 流未正确刷新导致写入不完整:saveCompressedData中仅调用out.pop(),可能未确保gzip压缩器的内部缓冲完全写入文件。如果压缩器还有未刷新的数据,会导致文件开头的size字段不完整或缺失,读取时自然得到错误字节。
  • 文件损坏或写入中断:写入过程中若出现磁盘空间不足、程序意外退出、文件被截断等情况,会导致文件数据不完整,读取时无法正确解析开头的size字段。
  • 类型大小的平台差异:代码中bid的大小用uint64_t写入,但close_size、tick_size用size_t写入。size_t的大小随平台变化(32位系统为4字节,64位为8字节),若写入和读取的平台size_t大小不同,会导致后续数据偏移,进而破坏整个文件的结构,连带着开头的size读取也出现错误。
  • 二进制模式未生效:虽然代码中指定了std::ios_base::binary打开文件,但在Windows等平台上,若编译时出现错误或代码被意外修改,导致文件以文本模式打开,会自动转换换行符,破坏二进制数据的字节结构,引发读取错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:03:17