不可不知的Linux中三種緩衝模式

今天來說說緩衝的事。也許你已經聽說過三種緩衝模式。標準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),回覆:領取學習資料。進入技術交流羣。網盤資料有如下:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章