今天來說說緩衝的事。也許你已經聽說過三種緩衝模式。標準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文件
會發現文件的長度是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打開就可能在終端顯示輸出信息啦。
或者,要想打印完後直接輸出到終端,只需要改成下面這樣就可以了:
printf("hello,minger\n");
不帶緩衝
此時標準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),回覆:領取學習資料。進入技術交流羣。網盤資料有如下: