在streambuffers之间进行数据块级复制

时间:2016-05-06 15:26:41

标签: c++ iostream streambuf

我想在std::streambuf个实例之间有效地复制数据。也就是说,我想在它们之间铲除数据块,而不是执行逐字符复制。例如,这是我正在寻找的东西:

stringbuf in{ios_base::in};
stringbuf out{ios_base::out};
copy(istreambuf_iterator<char>{in},
     istreambuf_iterator<char>{},
     ostreambuf_iterator<char>{out});

存在这样的语法糖,还有一些错误检查:

ostream os{&out};
os << &in;

以下是我的标准库(Mac OS X,XCode 7)中operator<<(basic_streambuf<..>*)实现的片段:

                typedef istreambuf_iterator<_CharT, _Traits> _Ip;
                typedef ostreambuf_iterator<_CharT, _Traits> _Op;
                _Ip __i(__sb);
                _Ip __eof;
                _Op __o(*this);
                size_t __c = 0;
                for (; __i != __eof; ++__i, ++__o, ++__c)
                {
                    *__o = *__i;
                    if (__o.failed())
                        break;
                }

底线是:这仍然是每个字符的复制。我希望标准库使用的算法依赖于streambuffers sputnsgetn的块级成员函数,而不是每个字符的传输。标准库是否提供了这样的算法,还是我必须自己编写?

1 个答案:

答案 0 :(得分:1)

我担心的答案是:标准库的当前设计是不可能的。原因是streambuffers完全隐藏了他们管理的角色序列。这使得无法直接将字节从一个streambuffer的get区域复制到另一个stretauffer的put区域。

如果&#34;输入&#34; streambuffer会暴露其内部缓冲区,然后是&#34;输出&#34; streambuffer可以使用sputn(in.data(), in.size())。或者更明显的是:如果输出缓冲区也暴露了它的内部缓冲区,那么可以使用普通memcpy来铲除两者之间的字节。其他I / O库以这种方式运行:例如,Google stream implementation的协议缓冲区。 Boost IOStreams有一个optimized implementation to copy between streams。在这两种情况下,都可以进行有效的块级复制,因为streambuffer等效提供了对其中间缓冲区的访问。

实际上,streambuffers甚至不需要缓冲区:当无缓冲操作时,每次读/写直接进入底层设备。据推测,这是标准库不支持内省的一个原因。不幸的结果是输入和输出流传输器之间不能有效复制。块级复制需要中间缓冲区,复制算法的操作如下:

  1. 通过sgetn从输入streambuffer读入中间缓冲区。
  2. 通过sputn从中间缓冲区写入输出streambuffer。
  3. 转到1.直到输入耗尽或写入输出streambuffer失败