今天來說說緩沖的事。也許你已經聽說過三種緩沖模式。标準I/O庫的緩沖主要分為3種:全緩沖、行緩沖和不緩沖。今天就3種緩沖寫了一些示例,以幫助了解。
I/O檔案流的緩沖類型
标準IO提供緩沖的目的是為了通過減少使用read和write調用的次數來提高IO讀寫的效率,它對每個IO流自動的進行緩沖處理,進而避免了使用者程式在使用read和write需要考慮的這一點。因為read和write是系統調用。《可以參考Linux 系統調用和庫函數》
标準IO流提供了三種緩沖。分别是全緩沖,行緩沖以及無緩沖。
全緩沖
在使用全緩沖的情況下,當資料填滿整個緩沖區之後才進行實際的IO操作。對于駐留在磁盤上的檔案的讀寫通常是使用全緩沖。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
FILE *fp;
if ((fp = fopen("./text.txt","w+")) == NULL){
printf("open file failed\n");
return -1;
}
char buf[] = "minger\n";
fwrite(buf,sizeof(char),sizeof(buf),fp);
//fflush(fp);
sleep(20); //延時一段時間,以便觀察。
fclose(fp);
return 0;
}
編譯輸出:
$ gcc main -o main.c
$ ./main
編譯執行這個程式,然後立馬檢視text.txt檔案
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0MDNxMDNxQTM1ADNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
會發現檔案的長度是0,原因在于它預設是全緩沖的,是以在将内容寫入檔案後,并沒有直接存在檔案中,當程式關閉檔案或者程式運作完成退出後,再次檢視:
除了等待程式運作完成,還可以使用fflush函數。fflush函數根據指定的檔案流将緩沖區的内容進行實際的操作,并清空緩沖區;如果參數為NULL,則會對所有打開的檔案流操作。
是以将fwrite下面一行的注釋去掉後,就可以發現,寫入之後,就可以直接在檔案中看到内容了。
行緩沖
在使用行緩沖的情況下,每當輸入輸出遇到換行或者緩沖區滿了的情況下才會進行實際的IO操作,當涉及到終端輸入輸出的時候通常使用行緩沖。
例子舉例:
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("hello,minger");
//fflush(stdout);//人為重新整理緩沖區
while(1);
return 0;
}
編譯運作:
$ gcc main.c -o main
$ ./main
你會發現,printf執行完了之後,内容并沒有馬上輸出到終端。
原因是printf 是标準I/O庫函數,往标準輸出輸出東西,是行緩沖,因為輸出的東西換行符, 是以資料存放在緩沖區中,沒有重新整理緩沖區。故不能輸出到螢幕上。
可以把注釋函數fflush打開就可能在終端顯示輸出資訊啦。
或者,要想列印完後直接輸出到終端,隻需要改成下面這樣就可以了:
不帶緩沖
此時标準IO庫不對字元進行緩沖存儲。這就使得輸入流要求IO立即進行,如标準錯誤流,若果出現錯誤,會立馬輸出。
#include <stdio.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
fprintf(stderr,"hello,minger");
sleep(10);
return 0;
}
編譯運作:
編譯運作你就會發現,運作完fprintf語句後,内容直接輸出在終端,而不需要等到換行。一般來說,标準錯誤是不帶緩沖的。
總結
标準錯誤永遠是無緩沖的。當标準輸入輸出指向的是互動式裝置(如終端)的時候,它們是行緩沖的。若不是則是全緩沖的。
歡迎關注公衆号【程式猿編碼】,添加本人微信号(17865354792),回複:領取學習資料。進入技術交流群。網盤資料有如下: