使用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引用无效指针。
修改步骤
- 刷新缓冲:在读取循环结束后,调用
BIO_flush(bio_b64)强制将缓冲的剩余编码内容写入文件。 - 正确释放资源:错误处理时使用
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
相关产品推荐
相关产品推荐

