从std :: string流没有复制? [英] Stream from std::string without making a copy?

查看:180
本文介绍了从std :: string流没有复制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网络客户端,请求方法需要一个 std :: streambuf * 。这个方法是通过 boost :: iostreams :: copy 实现的自定义 std :: streambuf 类知道如何写数据到网络API,这工作伟大。这意味着我可以将一个文件流式传输到请求中,而无需将其全部读入内存。

I have a network client with a request method that takes a std::streambuf*. This method is implemented by boost::iostreams::copy-ing it to a custom std::streambuf-derived class that knows how to write the data to a network API, which works great. This means I can stream a file into the request without any need to read it all into memory.

然而,在某些情况下,必须发送大块数据它们不在一个文件中,所以我包括一个重载,需要一个字符串。为了避免重复流中的所有网络代码,显然我应该建立一个 streambuf 表示字符串并调用其他方法。我可以想出这样做的唯一方法是:

There are some cases, however, where large blocks of data must be sent which are not in a file, so I included an overload that takes a string. To avoid duplicating all the network code in the stream, it seemed obvious that I should set up a streambuf representing the string and call the other method. The only way I could figure out to make this work was something like:

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

不幸的是, istringstream 数据,在某些情况下是几兆字节。在一般情况下,这是完全有道理的,当然,如果你把一个const引用一些对象,你不想要的对象,假设它可以继续使用该引用。

Unfortunately, istringstream makes a copy of the data, which in some cases is several megabytes. It makes perfect sense in the general case, of course, if you hand a const reference to some object you don't want that object assuming it can continue using that reference.

我用下面的工作:

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 * ?有没有更好的方法来做这个?

This seems to work just fine, but I wonder if it's really necessary. Why doesn't std::istringstream have an overload taking a std::string const *? Is there a better way to do this?

推荐答案

你有这些问题的原因是std :: string isn'真的适合你在做什么。一个更好的主意是在传递原始数据时使用char的向量。如果可能,我只是改变一切使用矢量,使用vector :: swap和引用的向量作为适当,以消除所有的复制。如果你喜欢iostreams / streambuf api,或者你必须处理一些需要streambuf的东西,那么创建你自己的使用向量的streambuf是很简单的,比如你的。它将有效地做同样的事情,你对与其他答案中列出的相同的问题,但你不会违反类的合同。

The reason you're having these problem is that std::string isn't really suited to what you're doing. A better idea is to use vector of char when passing around raw data. If its possible, I would just change everything to use vector, using vector::swap and references to vectors as appropriatte to eliminate all your copying. If you like the iostreams/streambuf api, or if you have to deal with something that takes a streambuf, it would be trivial to create your own streambuf that uses a vector, like yours. It would effectively do the same thing that you do with the same issues as listed in the other answers, but you wouldn't be violating the class's contract.

否则,我认为你所能得到的可能是最好的方式,而不是传递一个istringstream无处不在。

Otherwise, I think what you've got is probably the best way forward short of passing around an istringstream everywhere.

这篇关于从std :: string流没有复制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆