天天看點

标準IO緩沖

摘抄自《UNIX環境進階程式設計》 

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

    标準I/O提供了以下3種類型的緩沖。

    (1)全緩沖。在這種情況下,在填滿标準I/O緩沖區後才進行實際I/O操作。對于駐留在磁盤上的檔案通常是由标準I/O庫實施全緩沖的。在一個流上執行第一次I/O操作時,相關标準I/O函數通常調用malloc獲得需使用的緩沖區。

        術語沖洗(flush)說明标準I/O緩沖區的寫操作。緩沖區可由标準I/O例程自動地沖洗(例如,當填滿一個緩沖區時),或者可以調用函數fflush沖洗一個流。值得注意的是,在UNIX環境中,flush有兩種意思。在标準I/O庫方面,flush意味着将緩沖區中的内容寫到磁盤上(該緩沖區可能隻是部分填滿的)。在終端驅動程式方面,flush表示丢棄已存儲在緩沖區中的資料。

    (2)行緩沖。在這種情況下,當在輸入和輸出中遇到換行符時,标準I/O庫執行I/O操作。這允許我們一次輸出一個字元(用标準I/O函數fputc),但隻有在寫了一行之後才進行實際I/O操作。當流涉及一個終端時(如标準輸入和标準輸出),通常使用行緩沖。

    對于行緩沖有兩個限制。第一,因為标準I/O庫用來收集每一行的緩沖區的長度是固定的,是以隻要填滿了緩沖區,那麼即使還沒有寫一個換行符,也進行I/O操作。第二,任何時候隻要通過标準I/O庫要求從(a)一個不帶緩沖的流,或者(b)一個行緩沖的流(它從核心請求需要資料)得到輸入資料,那麼就會沖洗所有行緩沖輸出流。在(b)中帶了一個在括号中的說明,其理由是,所需的資料可能已在該緩沖區中,它并不要求 一定從核心讀資料。很明顯,從一個不帶緩沖的流中輸入(即(a)項)需要從核心獲得資料。

    (3)不帶緩沖。标準I/O庫不對字元進行緩沖存儲。例如,若用标準I/O函數fputs寫15個字元到不帶緩沖的流中,我們就期望這15個字元能立即輸出,很可能使用write函數将這些字元寫到相關聯的打開檔案中。

    标準錯誤流stderr通常是不帶緩沖的,這就使得出錯資訊可以盡快顯示出來,而不管它們是否含有一個換行符。

    ISO C要求下列緩沖特征。

        1、當且僅當标準輸入和标準輸出并不指向互動式裝置時,它們才是全緩沖的。

        2、标準錯誤絕不會是全緩沖的

        但是,這并沒有告訴我們如果标準輸入和标準輸出指向互動式裝置時,它們是不帶緩沖的還是行緩沖的;以及标準錯誤是不帶緩沖的還是行緩沖的。很多系統預設使用下列類型的緩沖:

        1、标準錯誤是不帶緩沖的

        2、若是指向終端裝置的流,則是行緩沖的;否則是全緩沖的。

繼續閱讀