c++ - 从 std::string 流式传输而不制作拷贝?

标签 c++ stl stringstream

我有一个网络客户端,其请求方法采用 std::streambuf*。此方法通过 boost::iostreams::copy 实现 - 将其转换为自定义 std::streambuf - 知道如何将数据写入网络 API 的派生类,效果很好。这意味着我可以将文件流式传输到请求中,而无需将其全部读入内存。

然而,在某些情况下,必须发送不在文件中的大数据 block ,因此我包含了一个采用字符串的重载。为了避免重复流中的所有网络代码,显然我应该设置一个表示字符串的 streambuf 并调用其他方法。我想出的唯一方法是:

std::istringstream ss(data);
send(ss.rdbuf());

不幸的是,istringstream 制作了数据的拷贝,在某些情况下,该拷贝有几兆字节。在一般情况下,这非常有意义,当然,如果您将 const 引用传递给某个对象,您不希望该对象假设它可以继续使用该引用。

我通过以下方法解决了这个问题:

struct zerocopy_istringbuf
    : public std::stringbuf
{
    zerocopy_istringbuf(std::string const* s)
        : std::stringbuf(std::ios::in)
    {
        char* p = const_cast<char*>(s->c_str());
        setg(p, p, p + s->length());
    }
};

...

send(&zerocopy_istringbuf(data));

这似乎工作得很好,但我想知道是否真的有必要。为什么 std::istringstream 没有采用 std::string const * 的重载?有更好的方法吗?

最佳答案

你遇到这些问题的原因是 std::string 并不真正适合你正在做的事情。一个更好的主意是在传递原始数据时使用 char vector 。如果可能的话,我会更改所有内容以使用 vector,使用 vector::swap 和对 vector 的引用作为适当的来消除所有复制。如果您喜欢 iostreams/streambuf api,或者如果您必须处理需要 streambuf 的东西,那么创建您自己的使用 vector 的 streambuf 将是微不足道的,就像您的一样。它会有效地做与您处理其他答案中列出的相同问题相同的事情,但您不会违反类(class)契约(Contract)。

否则,我认为除了到处传递 istringstream 之外,您所拥有的可能是最好的前进方式。

关于c++ - 从 std::string 流式传输而不制作拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1590062/

相关文章:

c++ - 如何阻止读取 C++ stringstream 以等待数据

C++字符串流转换错误: segmentation fault

c++ - 如何解决窗口焦点问题?

c++ - 我如何在我的程序中使用这个单链表结构来提高我的性能?

c++ - 使用纯 Windows API 设置 StaticText 控件文本,无 MFC

c++ - 尽可能小地从 Boost 中提取 sublib

c++ - Stringstream 到字符串逻辑 C++

c++ - '初始化' : cannot convert from 'zallocator<char>' to 'zallocator<U>'

c++ - 拆分 C++ 模板文件 intp cpp 和 hpp 文件

c++ - 在 STL map 中的所需位置插入元素