我有一个内存块(不透明),我想通过他们的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);
这是正确的方法吗?
答案 0 :(得分:41)
编写一个使用缓冲区的一次性std::streambuf
实际上是微不足道的,因为std::streambuf
的所有虚函数的默认行为都是'正确的事'。您只需setg
构建中的读取区域,underflow
和uflow
就可以安全地返回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已经提到的那样。