C++/Streambuf
streambuf 是w:C++標準程式庫中的一個w:頭文件,定義了C++標準中的流輸入輸出的基本模板類std::basic_streambuf。這是一個虛基類,用於派生具體的流緩衝區類。
簡介
編輯std::basic_streambuf中,用「開始位置」、「當前位置」、「結尾位置」3個屬性描述輸入或輸出緩衝區。在此之上定義了大量的非常基本的流緩衝區的常用操作函數,如讀/寫一個字符、讀n個字符、重定位當前指針、設置緩衝區的w:locale、設置鎖操作等等。其中具有公共訪問屬性的成員函數對所有流緩衝區是常用的;保護訪問屬性的w:虛成員函數需要在針對特定流緩衝區的派生類中有專門的實現。其它保護屬性的非虛成員函數是對流緩衝區的一些基本操作,如獲得緩衝區開始指針、當前指針、尾部指針等等。 C++標準庫中的其它流輸入輸出一般都是派生於std::basic_streambuf基類。
所有的流緩衝區實現遵循下屬約定:
- 受控字符序列(controlled character sequence),也稱作緩衝區,可包括:輸入序列(也稱get area)用於緩衝輸入操作;以及輸出序列(也稱put area)用於緩衝輸出操作。
- 被關聯的字符序列(associated character sequence),也稱源(source)用於輸入或者匯(sink)用於輸出。它可以是各種實體,如通過操作系統API訪問的文件,TCP socket,串口,其它字符設備;或者是一個對象(std::vector,array,stringw:字面量等)可被解釋為字符源或匯。
- 受控字符序列由3種指針描述:
- 開始指針eback或pbase,總是指向緩衝區的地址最低元素。
- 當前指針gptr或pptr(也稱作next pointer)指向下一個將要讀/寫的數據對象。如果next pointer為空,則緩衝區不存在;否則,可以安全比較緩衝區的開始指針、next pointer、尾指針的先後順序。
- 對於輸出緩衝區,如果next pointer小於尾指針,則可以在next pointer所指位置處存入一個數據。
- 對於輸入緩衝區,如果next pointer小於尾指針,則可以在next pointer所指位置處讀入一個數據。
- 對於輸入緩衝區,如果開始指針小於next pointer,可以在next pointer所指的回退位置(putback position)處回退仿製(put back)一個數據。
- 尾指針egptr或epptr(end pointer),指向緩衝區結尾後的下一個字符。
受控字符序列的字符表示與編碼可能與被關聯的字符序列不同。這種情況下典型使用一種w:locale facet:std::codecvt執行字符轉碼。如把UTF-8或其他多字節編碼文件通過std::wfstream對象讀入,這時受控字符序列由寬字符組成,但被關聯的字符序列由字節組成。
std::basic_streambuf的典型實現僅保持6個CharT*指針與一個std::locale拷貝作為數據成員。
streambuf
頭文件中還定義了basic_streambuf的兩個模板特化實例,分別針對字符類型與寬字符類型:
- typedef basic_streambuf<char, char_traits<char> > streambuf;
- typedef basic_streambuf<wchar_t, char_traits<wchar_t> > wstreambuf;
成員類型
編輯成員類型 | 定義 |
---|---|
char_type | CharT |
traits_type | Traits |
int_type | Traits::int_type |
pos_type | Traits::pos_type |
off_type | Traits::off_type |
成員函數
編輯- 虛析構函數:
- Locales
- pubimbue:調用最派生類的imbue()
- getloc:獲取流當前使用的locale。
- 定位
- pubsetbuf:調用setbuf()
- pubseekoff:調用seekoff()
- pubseekpos:調用seekpos()
- pubsync:調用sync()
- 輸入緩衝區(Get area)
- in_avail:獲取在輸入緩衝區直接可利用字符數量。
- snextc:推進指針一步,然後返回新的位置處的值
- sbumpc:讀出當前位置的值,然後推進指針一步。如果緩衝區的內容已經讀完,那麼sbumpc會調用uflow方法
- stossc:過時。推進指針一步
- sgetc:讀出當前位置的值,指針不變。如果緩衝區的內容已經讀完,那麼sgetc會調用underflow方法
- sgetn:調用xsgetn() 用於讀取多個字符
- 輸出緩衝區(Put area)
- sputc:向輸出緩衝區寫入一個字符,然後推進指針一步。如果緩衝區已經滿了或者沒有提供緩衝區,sputc會調用overflow,將數據寫入外部的匯並清空緩衝區。
- sputn:輸出多個字符。實際調用xsputn() ,而xsputn的默認操作是對每個字符調用sputc。
- 放回(Putback)
- sputbackc:把一個字符放回到輸入緩衝區
- sungetc:輸入緩衝區的指針向回移動一步,然後返回當前位置的值
- protected成員函數
- 構造函數
- operator=
- swap
- Locales
- imbue
- 定位
- setbuf:基類的該函數為空操作。派生類可重載此虛函數用自定義的緩衝區替換缺省的緩衝區。
- seekoff:基類的該函數為空操作。派生類可重載此虛函數,對緩衝區的當前指針相對尋址。
- seekpos:基類的該函數為空操作。派生類可重載此虛函數,對緩衝區的當前指針絕對尋址。
- sync:同步受控字符序列(即緩衝區)與被關聯的字符序列。對輸出緩衝區,典型是把其內容寫入到被關聯的序列;對輸入緩衝區,典型是放棄當前輸入緩衝區的內容,重新從被關聯序列讀入最新內容到輸入緩衝區。
- 輸入緩衝區(Get area)
- showmanyc
- underflow
- uflow 默認行為是調用underflow,然後移動緩衝區的讀取指針
- xsgetn 默認行為是依次調用sbumpc,如果為了改善讀取多個字符的性能,可以重寫xsgetn方法
- eback 輸入緩衝區開始位置
- gptr 輸入緩衝區當前位置
- egptr 輸入緩衝區結束位置
- gbump 推進get指針
- setg 設置輸入序列指針
- 輸出緩衝區(Put area)
- xsputn
- overflow
- pbase 輸出緩衝區開始位置
- pptr 輸出緩衝區當前位置
- epptr 輸出緩衝區結束位置
- pbump 增加當前寫入位置的指針
- setp 設置當前寫入位置的指針
- 放回(Putback)
- pbackfail
其它輔助模板類
編輯streambuf
頭文件中還定義了模板類std::istreambuf_iterator,用於描述從輸入流中讀取數據對象的基本操作。它從相關聯的basic_streambuf,定義了解引用(dereference)的*操作符、前綴++操作符、後綴++操作符、equal成員函數。
streambuf
頭文件中還定義了模板類std::ostreambuf_iterator,用於描述向輸出流中寫入數據對象的基本操作。它關聯一個輸出流basic_streambuf,定義了寫入一個字符的賦值操作符。其它操作符,如解引用(dereference)的*操作符、前綴++操作符、後綴++操作符,都是簡單地返回iterator自身。還定義了failed成員函數,查看寫入操作是否成功的內部標誌位_Failed。