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

使用BIO_f_base64()时BIO_write()无法写入文件的问题求助

问题:OpenSSL Base64编码后输出文件为空

我正在学习OpenSSL,编写了读取文件并将Base64编码内容写入另一文件的代码,但输出文件为空。程序能正常读取输入内容,运行时显示读写字节数一致,但最终文件没有内容。移除编码逻辑直接写入则功能正常,请求帮助。

有问题的编码代码

#include <iostream>
#include <openssl/ssl.h>
#include <openssl/bio.h>

#define MAX_BUFFER_SIZE 512

int main (int argc, char* argv[])
{
    BIO* bio_out = nullptr;
    BIO* bio_in = nullptr;
    BIO* bio_b64 = nullptr;
    int in_byte, out_byte;
    char buffer[MAX_BUFFER_SIZE];
    std::memset(buffer, '\0', MAX_BUFFER_SIZE);

    if (argc != 3)
    {
        std::cout << "Usage: bio_b64_encode <source-read> <encoded-write>\n";
        return 1;
    }

    bio_in = BIO_new_file(argv[1], "r");
    bio_out = BIO_new_file(argv[2], "wb");
    bio_b64 = BIO_new(BIO_f_base64());
    BIO_push(bio_b64, bio_out);

    in_byte = BIO_read(bio_in, buffer, MAX_BUFFER_SIZE);
    while (in_byte > 0)
    {
        std::cout << "Read " << in_byte << " bytes.\n";
        out_byte = BIO_write(bio_b64, buffer, in_byte);
        std::cout << "Wrote " << out_byte << " bytes.\n";
        if (in_byte != out_byte)
        {
            std::cout << "In bytes: " << in_byte << " and Out bytes: " << out_byte << " are not equal.\n";
            BIO_free(bio_in);
            BIO_free(bio_out);
            return 1;
        }
        in_byte = BIO_read(bio_in, buffer, MAX_BUFFER_SIZE);
    }

    BIO_free(bio_in);
    BIO_free_all(bio_b64);
    
    return 0;
}

程序运行输出

Read 22 bytes.
Wrote 22 bytes.

移除编码逻辑后正常的代码

#include <iostream>
#include <openssl/ssl.h>
#include <openssl/bio.h>

#define MAX_BUFFER_SIZE 512

int main (int argc, char* argv[])
{
    BIO* bio_out = nullptr;
    BIO* bio_in = nullptr;
    BIO* bio_b64 = nullptr;
    int in_byte, out_byte;
    char buffer[MAX_BUFFER_SIZE];
    std::memset(buffer, '\0', MAX_BUFFER_SIZE);

    if (argc != 3)
    {
        std::cout << "Usage: bio_write <file-read> <file-write>\n";
        return 1;
    }

    bio_in = BIO_new_file(argv[1], "r");
    bio_out = BIO_new_file(argv[2], "w");

    in_byte = BIO_read(bio_in, buffer, MAX_BUFFER_SIZE);
    while (in_byte > 0)
    {
        std::cout << "Read " << in_byte << " bytes.\n";
        out_byte = BIO_write(bio_out, buffer, in_byte);
        std::cout << "Wrote " << out_byte << " bytes.\n";
        if (in_byte != out_byte)
        {
            std::cout << "In bytes: " << in_byte << " and Out bytes: " << out_byte << " are not equal.\n";
            BIO_free(bio_in);
            BIO_free(bio_out);
            return 1;
        }
        in_byte = BIO_read(bio_in, buffer, MAX_BUFFER_SIZE);
    }

    BIO_free(bio_in);
    BIO_free_all(bio_out);
    
    return 0;
}

解决方案

问题根源在于Base64 BIO的缓冲机制:Base64编码以3字节输入为单位生成4字节输出,当输入字节数不是3的倍数时,剩余的字节会被临时缓冲在BIO中,不会立即写入文件。此外,原代码的错误处理存在资源释放风险,直接释放bio_out会导致bio_b64引用无效指针。

修改步骤

  1. 刷新缓冲:在读取循环结束后,调用BIO_flush(bio_b64)强制将缓冲的剩余编码内容写入文件。
  2. 正确释放资源:错误处理时使用BIO_free_all(bio_b64)释放整个BIO链(包含bio_out),避免重复释放。

修改后的核心代码片段

// 循环结束后添加刷新操作
BIO_flush(bio_b64);

BIO_free(bio_in);
BIO_free_all(bio_b64);

错误处理部分修改

if (in_byte != out_byte)
{
    std::cout << "In bytes: " << in_byte << " and Out bytes: " << out_byte << " are not equal.\n";
    BIO_free(bio_in);
    BIO_free_all(bio_b64); // 释放整个BIO链,自动包含bio_out
    return 1;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:10:35