Linux標準I/O之緩衝

緩衝

標準I/O庫提供緩衝的目的是儘可能地減少使用read和write調用的次數。他也對每個I/O流自動地進行緩衝管理,從而避免了應用程序需要考慮這一點所帶來的麻煩。不幸的是,標準I/O庫最令人迷惑的也是他的緩衝。

標準I/O提供了三種類型的緩衝:

全緩衝

在填滿標準IO緩衝區後才進行實際IO操作。對於駐留在磁盤上的文件通常是由標準IO庫實施全緩衝的,在一個流上執行第一次IO操作時,相關標準IO函數通常調用malloc獲得需使用的緩衝區。
術語沖洗說明I/O緩衝區的寫操作。緩衝區可由標準I/O例程自動沖洗,或者可以調用函數fflush沖洗一個流。值得引起注意的是在UNIX環境 中,flush有兩種意思。在標準I/O庫方面,flush意味着將緩衝區中的內容寫到磁盤上。在終端驅動程序方面flush表示丟棄已存儲在緩衝區中的數據。

行緩衝

在這種情況下,當在輸入和輸出中遇到換行符時,標準I/O庫執行I/O操作。這允許我們一次輸出一個字符,但只有在寫了一行之後才進行實際I/O操作。當流涉及一個終端時,通常使用行緩衝。
對於行緩衝有兩個限制。第一,因爲標準I/O庫用來收集每一行的緩衝區的長度是固定的,所以只要填滿了緩衝區,那麼即使沒有寫一個換行符,也進行I/O操 作。第二,任何時候只要通過標準I/O庫要求從a一個布袋緩衝的流,或者b一個行緩衝的流得到輸入數據,那麼就會造成沖洗所有行緩衝輸出流。在b中帶了一 個在括號中的說明,其理由是,所需的數據可能已在緩衝區中,他並不需求在需要數據時才從內核讀數據。很明顯,從不帶緩衝的一個流中進行輸入要求當時從內核得到數據。

不帶緩衝

標準I/O庫不對字符進行緩衝存儲。例如,如果用I/O函數fputs寫15個字符到不帶緩衝的流中,則該函數很可能用write系統調用函數將這些字符立即寫至相關聯的打開文件中。
標準出錯流stderr通常是不帶緩衝的,這就使得出錯信息可以儘快顯示出來,而不管它們是否含有一個換行符。

ISO C要求下列緩衝特徵:

  • 當且僅當標準輸入和標準輸出並不涉及交互式設備使,他們纔是全緩衝的。

  • 標準出錯絕不會使全緩衝的。

但是,這並沒有告訴我們如果標準輸入和標準輸出涉及交互式設備時,他們是不帶緩衝的還是行緩衝的;以及標準出錯時不帶緩衝的還是行緩衝的。很多系統默認使用下列類型的緩衝:

  • 標準出錯是不帶緩緩衝的。

  • 如若是涉及終端設備的其他流,則他們是行緩衝的;否則是全緩衝的。


更改緩衝區類型

對任何一個給定的流,如果我們並不喜歡這些系統默認的情況,則可調用下列函數中的一個更改緩衝類型:

void setbuf(FILE *restrict fp, char *restrict buf)
int setvbuf(FILE *restrict fp, char *restrict buf,int mode,size_t size)
發佈了31 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章