跳至內容

C++/Streambuf

維基教科書,自由的教學讀本
< C++

streambufw: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。

參考文獻

[編輯]