我一直在研究创建自己的ostream以及一个streambuf来处理我的ostream的缓冲区。我实际上大部分工作,我可以插入(<<)到我的流并获得字符串没有问题。我通过虚拟函数xsputn来实现这一点。但是,如果我向流输入(<<<&)一个浮点数或一个int而不是字符串xsputn永远不会被调用。
我已经遍历了代码,我看到流正在调用do_put,然后是f_put,它最终会尝试将float 1字符一次放入缓冲区。我可以让它调用我的虚函数溢出(int c)的实现,如果我让我的缓冲区没有空格,从而得到浮点数和int的数据。
现在问题就在这里,我需要知道何时将float放入缓冲区。换句话说,我需要知道这是什么时候最后一次溢出将被调用一个特定的值流入.xsputn对我有用的原因是因为我得到了整个值及其长度。所以我可以将它复制到缓冲区然后调用等待缓冲区已满的函数。
我无可否认地滥用了ostream设计,因为我需要缓存输出,然后对每个输入值(<<<<<<<<<<<<<<
无论如何要清楚我会以另一种方式重申我正在拍摄的内容。我很有可能以错误的方式解决这个问题。
我想使用继承的ostream和streambuf所以我可以输入值并允许它为我处理我的类型转换,然后我想将这些信息传递给另一个对象,我将句柄传递给streambuf到(for?)。该对象有昂贵的i / o所以我不想一次发送数据1个字符。
如果不清楚,请提前抱歉。谢谢你的时间。
答案 0 :(得分:16)
虽然听起来很粗糙,但你做的不太清楚
对。只是为了确定:您提供的所有ostream
都是
便利构造函数来创建和安装streambuf
,
析构函数,可能是rdbuf
的实现
处理正确类型的缓冲区。假设这是真的:
在xsputn
中定义streambuf
纯粹是一种优化。
您必须定义的关键功能是overflow
。最简单的
overflow
的实现只需要一个字符,并且
将其输出到接收器。除此之外的一切都是优化:
例如,您可以使用setp
设置缓冲区;如果你这样做
这样,只有当缓冲区被调用时才会调用overflow
已满,或请求同花。在这种情况下,你必须
输出缓冲区也是如此(使用pbase
和pptr
来获取
地址)。 (streambuf
基类初始化
用于创建0长度缓冲区的指针,因此overflow
将是。imbue
呼唤每个角色。)你可能会做的其他功能
想要覆盖(非常)特定情况:
setbuf
:如果出于某种原因需要语言环境。 (记住这一点
当前字符编码是语言环境的一部分。)
seekoff
:允许客户端代码指定缓冲区。 (恕我直言,是的
通常不值得打扰,但你可能有特殊之处
要求。)
streambuf
:支持寻求。我从来没有在任何一个中使用过它
我的sync
,所以除了什么之外我不能提供任何信息
你可以阅读标准。
setp
:在flush上调用,应输出中的任何字符
缓冲到水槽。如果你从不打电话给overflow
(所以没有
缓冲区),你总是在同步,这可能是一个无操作。
uflow
或sync
可以拨打此电话,或者两者都可以拨打电话
单独的功能。 (关于uflow
之间的唯一区别
而uflow
只有sync
才会被调用
一个缓冲区,如果缓冲区为空,它将永远不会被调用。
如果客户端代码刷新流,则将调用overflow
。)
编写自己的流时,除非性能要求
否则,我会保持简单,只覆盖write(address, length)
。
如果性能指示缓冲区,我通常会将代码放入
将缓冲区刷新为单独的overflow
功能,并实现sync
和int MyStreambuf::overflow( int ch )
{
if ( pbase() == NULL ) {
// save one char for next overflow:
setp( buffer, buffer + bufferSize - 1 );
if ( ch != EOF ) {
ch = sputc( ch );
} else {
ch = 0;
}
} else {
char* end = pptr();
if ( ch != EOF ) {
*end ++ = ch;
}
if ( write( pbase(), end - pbase() ) == failed ) {
ch = EOF;
} else if ( ch == EOF ) {
ch = 0;
}
setp( buffer, buffer + bufferSize - 1 );
}
return ch;
}
int sync()
{
return (pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed)
? 0
: -1;
}
的:
xsputn
一般情况下,我不会打扰streamsize xsputn(char const* p, streamsize n)
{
streamsize results = 0;
if ( pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed ) {
if ( write(p, n) != failed ) {
results = n;
}
}
setp( buffer, buffer + bufferSize - 1 );
return results;
}
,但如果是您的客户
代码输出了很多长字符串,它可能很有用。
这样的事情可以解决问题:
{{1}}