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

C++17封装C read函数:如何返回可变大小数据并告知长度?

方案选择与实现建议

结论:选std::vector<char>,完全没必要用std::queue<char>

原因分析

你的场景核心是单次读取结果的传递:每次调用read包装方法,只需要把本次读到的有效字节传递给上层,上层自己负责拼接构建消息。

  • std::vector<char>完美匹配需求:
    1. 天然支持可变大小,可以精准存储本次读到的n个字节(不会浪费空间,也不会溢出)。
    2. 上层可以直接通过size()获取读取长度,满足拼接需求。
    3. 连续内存布局和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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:01:00