从内存缓冲区初始化C ++ std :: istringstream?

时间:2009-09-19 12:28:57

标签: c++ streambuf

我有一个内存块(不透明),我想通过他们的C ++适配器存储在mySQL的Blob中。适配器需要一个istream:

virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;

所以我的问题是:如何从这个内存块创建一个std :: istream(键入为char *)。它不是一个字符串,因为它不是以空值终止的(但我知道它的长度当然)。

如果没有复制我的内存块,例如在std :: string中,我找不到办法。我认为这有点浪费。这样的事情不起作用:

    std::streambuf istringbuf(blockPtr, blockLength);
    std::istringstream tmp_blob(&istringbuf);

因为std :: streambuf没有这样的构造函数。我看到了以下建议。

    std:: istringstream       tmp_blob;
    tmp_blob.rdbuf()->pubsetbuf(blockPtr, blockLength);

这是正确的方法吗?

4 个答案:

答案 0 :(得分:41)

编写一个使用缓冲区的一次性std::streambuf实际上是微不足道的,因为std::streambuf的所有虚函数的默认行为都是'正确的事'。您只需setg构建中的读取区域,underflowuflow就可以安全地返回traits_type::eof(),因为初始获取区域的末尾是流的结尾

e.g:

#include <streambuf>
#include <iostream>
#include <istream>
#include <ostream>

struct OneShotReadBuf : public std::streambuf
{
    OneShotReadBuf(char* s, std::size_t n)
    {
        setg(s, s, s + n);
    }
};

char hw[] = "Hello, World!\n";

int main()
{
    // In this case disregard the null terminator
    OneShotReadBuf osrb(hw, sizeof hw - 1);
    std::istream istr(&osrb);

    istr >> std::cout.rdbuf();
}

答案 1 :(得分:8)

查看std :: istrstream它有一个构造函数

 istrstream( char* pch, int nLength );

这个类有点折旧,或者至少你被告知使用其他类 strstream的问题是管理char *缓冲区的内存比较复杂,所以一般来说你更喜欢stringstream,因为它为你做了内存管理。但是在这种情况下,您已经在管理char *的内存,因此在这种情况下,正常的好处是成本。事实上,在这种情况下,strstream完全符合您的要求,并且代码或速度的开销最小。这类似于对ostrsteram by Herb Sutter

的讨论

答案 2 :(得分:5)

Boost.IOStreams有一个像stringstream一样工作的流,但包装了一个原生数组,因此你可以避免复制数据。

std :: stringstream总是创建自己的内部缓冲区

答案 3 :(得分:-1)

未经测试但也许值得一试......

std::stringstream ss;
ss.write( blockPtr, blockLength );
ss.seekg(0);

然后用ss调用setBlob函数。你的std :: stringstream中的内部缓冲区仍然像jalf已经提到的那样。