我有一个网络客户端,其请求方法采用 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/