天天看點

不可不知的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檔案

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

會發現檔案的長度是0,原因在于它預設是全緩沖的,是以在将内容寫入檔案後,并沒有直接存在檔案中,當程式關閉檔案或者程式運作完成退出後,再次檢視:

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

除了等待程式運作完成,還可以使用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;
}

           

編譯運作:

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

編譯運作你就會發現,運作完fprintf語句後,内容直接輸出在終端,而不需要等到換行。一般來說,标準錯誤是不帶緩沖的。

總結

标準錯誤永遠是無緩沖的。當标準輸入輸出指向的是互動式裝置(如終端)的時候,它們是行緩沖的。若不是則是全緩沖的。

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

歡迎關注公衆号【程式猿編碼】,添加本人微信号(17865354792),回複:領取學習資料。進入技術交流群。網盤資料有如下:

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

繼續閱讀