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

无法将特定内容写入stringstream?附二进制文件读取示例代码

解决二进制数据写入std::stringstream的问题

我看了你的代码,能发现几个关键问题导致你无法把二进制内容正确写入std::stringstream,我来帮你逐一排查并修正:

1. 不完整的std::stringstream初始化

你代码里的初始化语句new std::stringstream("", std::ios_base::app | s...是不完整的,而且处理二进制数据时必须显式指定二进制模式——默认的文本模式会自动转换换行符等特殊字符,直接破坏二进制数据的完整性。正确的初始化应该是:

raw_data_buffer = new std::stringstream(std::ios_base::out | std::ios_base::binary | std::ios_base::app);

2. 缺失写入stringstream的核心步骤

你已经从文件把数据读到了buf里,但根本没把buf的内容写入raw_data_buffer!这是最关键的遗漏,需要添加write操作:

raw_data_buffer->write(buf, 40);

3. 未做文件打开失败的检查

如果1.raw不存在、权限不足或者路径错误,文件打开会直接失败,后续的read操作只会得到无效的垃圾数据。一定要先校验文件状态:

is.open("1.raw", std::ios::binary);
if (!is.is_open()) {
    fprintf(stderr, "无法打开文件1.raw\n");
    free(buf);
    return EXIT_FAILURE;
}

4. 内存泄漏与不安全的内存分配

你用malloc分配的buf没有释放,会造成内存泄漏。对于固定大小的缓冲区,用栈上数组或者智能指针更安全省心:

// 推荐用栈上数组,自动释放无需手动管理
char buf[40];
// 或者用智能指针(适合动态大小场景)
std::unique_ptr<char[]> buf(new char[40]);

5. 全局动态stringstream的隐患

全局的std::stringstream*指针不仅容易忘记释放,也不符合C++的最佳实践。建议改用局部对象,或者记得在程序结束前手动释放:

// 程序末尾释放指针,避免内存泄漏
delete raw_data_buffer;

修正后的完整代码

#include <sstream>
#include <cstdio>
#include <fstream>
#include <cstdlib>
#include <memory> // 用于std::unique_ptr

int main() {
    std::ifstream is;
    is.open("1.raw", std::ios::binary);
    if (!is.is_open()) {
        fprintf(stderr, "无法打开文件1.raw\n");
        return EXIT_FAILURE;
    }

    // 用智能指针管理缓冲区,自动释放
    std::unique_ptr<char[]> buf(new char[40]);
    // 读取数据并检查是否成功
    is.read(buf.get(), 40);
    if (!is) {
        fprintf(stderr, "读取文件失败,实际读取了%d字节\n", static_cast<int>(is.gcount()));
    }

    // 打印读取的十六进制内容(转成unsigned char避免负数补码问题)
    for (int i = 0; i < 40; i++) {
        printf("%02X ", static_cast<unsigned char>(buf[i]));
    }
    printf("\n");

    // 初始化二进制模式的stringstream
    std::stringstream raw_data_buffer(std::ios_base::out | std::ios_base::binary);
    // 将二进制数据写入stringstream
    raw_data_buffer.write(buf.get(), 40);

    // 验证写入结果:导出stringstream内容并打印
    std::string data_str = raw_data_buffer.str();
    printf("stringstream中的内容(十六进制):\n");
    for (unsigned char c : data_str) {
        printf("%02X ", c);
    }
    printf("\n");

    return EXIT_SUCCESS;
}

额外提示

  • 打印char类型的十六进制时,一定要转成unsigned char,否则负数会被当成补码打印(比如0xFF会显示为FFFFFFFF)。
  • 如果文件大小小于40字节,is.read()会读到文件末尾,此时可以用is.gcount()获取实际读取的字节数,避免处理无效数据。
  • 尽量避免使用全局动态分配的对象,局部对象在作用域结束时会自动销毁,更安全可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:37:25