Tim*_*ter 9 c++ stl stringstream
我有一个网络客户端,其请求方法需要一个std::streambuf*
.这个方法是通过将boost::iostreams::copy
它发送到一个自定义std::streambuf
类来实现的,该类知道如何将数据写入网络API,这很有效.这意味着我可以将文件流式传输到请求中,而无需将其全部读入内存.
但是,在某些情况下,必须发送不在文件中的大块数据,因此我包含了一个带字符串的重载.为了避免重复流中的所有网络代码,我应该设置一个streambuf
代表字符串并调用另一个方法.我能弄清楚这项工作的唯一方法是:
std::istringstream ss(data);
send(ss.rdbuf());
Run Code Online (Sandbox Code Playgroud)
不幸的是,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));
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,但我想知道它是否真的有必要.为什么没有std::istringstream
过载std::string const *
?有一个更好的方法吗?
您遇到这些问题的原因是 std::string 并不真正适合您正在做的事情。更好的想法是在传递原始数据时使用 char 向量。如果可能的话,我会改变一切以使用向量,使用向量::交换和对向量的适当引用来消除所有复制。如果您喜欢 iostreams/streambuf api,或者如果您必须处理需要 Streambuf 的东西,那么创建您自己的使用向量的 Streambuf(就像您的一样)将是微不足道的。它实际上会做与其他答案中列出的相同问题相同的事情,但您不会违反班级的合同。
否则,我认为你所拥有的可能是最好的前进方式,而不是到处传递 istringstream。
归档时间: |
|
查看次数: |
2155 次 |
最近记录: |