天天看點

【Linux系統程式設計】 淺談标準I/O緩沖區 全緩沖: 行緩沖: 不帶緩沖:

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

标準I/O提供了三種類型的緩沖:

1、全緩沖: 在填滿标準I/O緩沖區後才進行實際I/O操作。正常檔案(如普通文本檔案)通常是全緩沖的。 2、行緩沖: 當在輸入和輸出中遇到換行符時,标準I/O庫執行I/O操作。這允許我們一次輸出一個字元,但隻有在寫了一行之後才進行實際I/O操作。标準輸入和标準輸出對應終端裝置(如螢幕)時通常是行緩沖的。 3、不帶緩沖: 使用者程式每次調庫函數做寫操作都要通過系統調用寫回核心(如系統調用函數)。标準錯誤輸出通常是無緩沖的,這樣使用者程式産生的錯誤資訊可以盡快輸出到裝置。

下面是各個緩沖區的驗證。

int main(int argc, char *argv[])  

{  

    FILE *fp = NULL;  

    // 讀寫方式打開,檔案不存在則建立  

    fp = fopen("sunplusedu.txt", "w+");  

    if(NULL == fp)  

    {  

        printf("open error\n");  

        return 1;  

    }  

    char *str = "sunplusedu\n";  

    fwrite(str, 1, strlen(str), fp);    // 往檔案寫内容  

    while(1);   // 程式阻塞在這裡  

    return 0;  

}  

運作程式發現,sunplusedu.txt并沒有内容。因為正常檔案通常是全緩沖的,隻有緩沖區滿了後,才會把内容寫到檔案中。接下來,我們改一下上面那個例子。

#include <stdio.h>  

#include <string.h>  

    int i = 0;  

    while(i <= 512){ // 緩沖區大小不确定,i的大小隻是一個調試值  

        fwrite(str, 1, strlen(str), fp);    // 往檔案寫内容  

        i++;  

上面的例子是循環給檔案寫内容,讓緩沖區有填滿的可能,結果發現,檔案是有内容的。實際上要想成功給檔案寫進内容,除了緩沖區填滿,還有别的方法。

1)人為關閉檔案,就算緩沖區沒有填滿,内容也會寫進檔案

    fclose(fp);     // 人為關閉檔案,就算緩沖區沒有填滿,内容也會寫進檔案  

2)程式正常結束,就算緩沖區沒有填滿,沒有關閉檔案,内容也會寫進檔案。

    // 程式正常結束,就算緩沖區沒有填滿,沒有關閉檔案,内容也會寫進檔案。  

    printf("hello sunplusedu");  

    while(1);  

運作這個程式,會發現 hello sunplusedu 并沒有列印到螢幕上。因為标準輸入和标準輸出對應終端裝置時通常是行緩沖的,當在輸入和輸出中遇到換行符時,标準I/O庫執行I/O操作。如下:

    printf("hello sunplusedu\n");  

除了遇到換行符,還有别的方法可以執行I/O操作。

1)緩沖區填滿

    while(1){   // 循環列印,總有緩沖區填滿的可能  

        printf("hello sunplusedu");  

2)人為重新整理緩沖區

    fflush(stdout); // 人為重新整理  

3)程式正常結束

    // 程式正常結束  

#include <unistd.h>  

    char *str = "hello sunplusedu.com";   

    // 有沒有\n,緩沖區有沒有填滿,都沒關系  

    write(1, str, strlen(str)); // 往标準輸出寫内容  

}  

繼續閱讀