[英]Block-level copying of data between streambuffers
我想在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 << ∈
這是我標准庫(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, sputn
和sgetn
的塊級成員函數,而不是每個字符的傳輸。 標准庫是否提供了這樣的算法,還是我必須自己編寫?
我擔心的答案是:標准庫的當前設計是不可能的。 原因是streambuffers完全隱藏了他們管理的角色序列。 這使得無法直接將字節從一個streambuffer的get區域復制到另一個stretauffer的put區域。
如果“輸入”streambuffer將暴露其內部緩沖區,那么“輸出”streambuffer可以只使用sputn(in.data(), in.size())
。 或者更明顯的是:如果輸出緩沖區也暴露了它的內部緩沖區,那么可以使用普通的memcpy
來挖掘兩者之間的字節。 其他I / O庫以這種方式運行:例如,Google協議緩沖區的流實現 。 Boost IOStreams具有在流之間進行復制的優化實現 。 在這兩種情況下,都可以進行有效的塊級復制,因為streambuffer等效提供了對其中間緩沖區的訪問。
實際上,streambuffers具有諷刺意味的是甚至不需要緩沖區:當無緩沖操作時,每個讀/寫直接進入底層設備。 據推測,這是標准庫不支持內省的一個原因。 不幸的結果是輸入和輸出流傳輸器之間不能有效復制。 塊級復制需要中間緩沖區,復制算法的操作如下:
sgetn
從輸入streambuffer sgetn
入中間緩沖區。 sputn
從中間緩沖區寫入輸出streambuffer。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.