C++17封装C read函数:如何返回可变大小数据并告知长度?
方案选择与实现建议
结论:选std::vector<char>,完全没必要用std::queue<char>
原因分析
你的场景核心是单次读取结果的传递:每次调用read包装方法,只需要把本次读到的有效字节传递给上层,上层自己负责拼接构建消息。
std::vector<char>完美匹配需求:- 天然支持可变大小,可以精准存储本次读到的n个字节(不会浪费空间,也不会溢出)。
- 上层可以直接通过
size()获取读取长度,满足拼接需求。 - 连续内存布局和
read()的缓冲区特性一致,数据拷贝效率高。
std::queue<char>完全不适合:
queue是FIFO容器,设计用来缓存多批次数据,但你的场景里不需要在read方法层做缓存——上层要自己拼接,返回queue反而会让上层需要逐个取出元素,既增加复杂度又降低效率。
具体实现示例(C++17)
利用std::unique_ptr<std::vector<char>>实现"有数据返回对象,无数据返回nullptr"的需求:
#include <vector> #include <memory> #include <unistd.h> #include <errno.h> class FDIO { private: char tmp_buf[4096]; // 全局对象的成员,每次调用会被覆盖 int fd; public: FDIO(int target_fd) : fd(target_fd) {} std::unique_ptr<std::vector<char>> read() { ssize_t read_bytes = ::read(fd, tmp_buf, sizeof(tmp_buf)); // 处理读取结果 if (read_bytes <= 0) { // 处理被信号中断的情况(EINTR),可重试一次 if (read_bytes == -1 && errno == EINTR) { read_bytes = ::read(fd, tmp_buf, sizeof(tmp_buf)); if (read_bytes <= 0) { return nullptr; } } else { // 无数据(EOF)或读取错误,返回nullptr return nullptr; } } // 把有效数据拷贝到vector并返回 auto data = std::make_unique<std::vector<char>>(); data->assign(tmp_buf, tmp_buf + read_bytes); return data; } };
上层使用示例
上层可以拿到vector后直接拼接数据:
// 假设fd_io是全局的FDIO实例 std::vector<char> full_message; while (auto chunk = fd_io.read()) { full_message.insert(full_message.end(), chunk->begin(), chunk->end()); // 这里可以判断full_message是否构成完整消息,做后续处理 }
内容的提问来源于stack exchange,提问作者MrBit
相关产品推荐
相关产品推荐

