華清遠見嵌入式學院講師。
a)緩衝區機制
根據應用程式對檔案的訪問方式,即是否存在緩衝區,對檔案的訪問可以分為帶緩衝區的操作和非緩衝區的檔案操作:
a) 帶緩衝區檔案操作:高階標準檔案i/o操作,將會在使用者空間中自動為正在使用的檔案開闢記憶體緩衝區。
b) 非緩衝區檔案操作:低階檔案i/o操作,讀寫檔案時,不會開闢對檔案操作的緩衝區,直接通過系統呼叫對磁碟進行操作(讀、寫等),當然用於可以在自己的程式中為每個檔案設定緩衝區。
兩種檔案操作的解釋和比較:
1、非緩衝的檔案操作訪問方式,每次對檔案進行一次讀寫操作時,都需要使用讀寫系統呼叫來處理此操作,即需要執行一次系統呼叫,執行一次系統呼叫將涉及到cpu狀態的切換,即從使用者空間切換到核心空間,實現程序上下文的切換,這將損耗一定的cpu時間,頻繁的磁碟訪問對程式的執行效率造成很大的影響。
2、ansi標準c庫函式 是建立在底層的系統呼叫之上,即c函式庫檔案訪問函式的實現中使用了低階檔案i/o系統呼叫,ansi標準c庫中的檔案處理函式為了減少使用系統呼叫的次數,提高效率,採用緩衝機制,這樣,可以在磁碟檔案進行操作時,可以一次從檔案中讀出大量的資料到緩衝區中,以後對這部分的訪問就不需要再使用系統呼叫了,即需要少量的cpu狀態切換,提高了效率。
b)緩衝型別
標準i/o提供了3種型別的緩衝區。
1、全緩衝區:這種緩衝方式要求填滿整個緩衝區後才進行i/o系統呼叫操作。對於磁碟檔案的操作通常使用全緩衝的方式訪問。第一次執行i/o操作時,ansi標準的檔案管理函式通過呼叫malloc函式獲得需要使用的緩衝區,預設大小為8192。
//come from /usr/include/stdio.h
/* default buffer size. */
#ifndef bufsiz
# define bufsiz _io_bufsiz //bufsiz 全域性巨集定義
#endif
//come from /usr/include/libio.h
#define _io_bufsiz _g_bufsiz
//come from /usr/include/_g_config.h
#define _g_bufsiz 8192 //真實大小
2、行緩衝區:在這種情況下,當在輸入和輸出中遇到換行符時,標準i/o庫函式將會執行系統呼叫操作。當所操作的流涉及乙個終端時(例如標準輸入和標準輸出),使用行緩衝方式。因為標準i/o庫每行的緩衝區長度是固定的,所以只要填滿了緩衝區,即使還沒有遇到換行符,也會執行i/o系統呼叫操作,預設行緩衝區的大小為1024。
下面的兩個程式的對比可以得出行緩衝的大小:
3、無緩衝區:
無緩衝區是指標準i/o庫不對字元進行快取,直接呼叫系統呼叫。標準出錯流stderr通常是不帶緩衝區的,這使得出錯資訊能夠盡快地顯示出來。
注:①標準輸入和標準輸出裝置:當且僅當不涉及互動作用裝置時,標準輸入流和標準輸出流才是全緩衝的。②標準錯誤輸出裝置:標準出錯絕不會是全緩衝方式的。
對於任何乙個給定的流,可以呼叫setbuf()和setvbuf()函式更改其緩衝區型別。
此函式第乙個引數為要操作的流物件,第二個引數buf 必須指向乙個長度bufsiz 的緩衝區。如果將buf 設定為null,則關閉緩衝區。如果執行成功,將返回0,否則返回非0 值。
此函式第乙個引數為要操作的流物件;第二個引數buf 必須指向乙個長為bufsiz 的緩衝區;第三個引數為緩衝區型別,分別定義如下:
//come from /usr/include/stdio.h
/* the possibilities for the third argument to 'setvbuf'. */
#define _iofbf 0 /* fully buffered.*/ //全緩衝
#define _iolbf 1 /* line buffered. */ //行緩衝
#define _ionbf 2 /* no buffering. */ //無緩衝
第四個引數為該buf的大小。如果指定乙個不帶緩衝區的流,則忽略buf和size引數。
如果指定全緩衝區或行緩衝區,則buf 和size 可選擇地指定乙個緩衝區及其長度。如果出現指定該流是帶緩衝區的,而buf 是null,則標準i/o 庫將自動為該流分配適當長度的緩衝,適當長度指的即是由檔案屬性資料結構(struct stat)的成員st_blksize 所指定的值,如果系統不能為該流決定此值(例如若此流涉及乙個裝置或乙個管道),則分配長度bufsiz 的緩衝區。
此函式如果執行成功,將返回0,否則返回非0 值。
以下是乙個修改 buf 大小寫檔案的例項程式。其源**如下:
#include < stdio.h>
#include < stdlib.h>
int main()
setbuf(fp,null);
fwrite(msg1,7,1,fp);
printf("test setbuf(no buf)!check no_buf1.txt\n");//檢視 buf 情況
printf("press enter to continue!\n");
getchar();
fclose(fp);//關閉流,因此將回寫 buf(如果有 buf 的話)
/*開啟(或者建立)乙個檔案,然後使用 setvbuf 設定為 nobuf 情況,並檢查關閉前流的情況*/
if((fp = fopen("no_buf2.txt","w")) == null)
setvbuf(fp,null,_ionbf,0); //設定為無 buf
fwrite(msg1,7,1,fp);
printf("test setbuf(no buf)!check no_buf1.txt\n"); //檢視 buf 情況
printf("press enter to continue!\n");
getchar();
fclose(fp);//關閉流,因此將回寫 buf ( 如果有 buf 的話)
if((fp = fopen("1_buf.txt","w")) == null)
setvbuf(fp,buf,_iolbf,sizeof(buf)); //設定為行 buf
fwrite(msg2,sizeof(msg2),1,fp); //寫內容
printf("test setvbuf(line buf)!check 1_buf.txt,because line buf,only data before enter send to file\n"); //檢視 buf 情況
printf("press enter to continue!\n");
getchar();
fclose(fp); //關閉流,因此將回寫 buf
//開啟(或者建立)乙個檔案,然後使用 setvbuf 設定為全 buf情況,並檢查關閉前流的情況
if((fp = fopen("f_buf.txt","w")) == null)
setvbuf(fp,buf,_iofbf,sizeof(buf));
for(i = 0;i < 2;i++)
printf("test setbuf(full buf)! check f_buf.txt\n");
printf("press enter to continue!\n");
getchar();
fclose(fp);//關閉流,因此將回寫 buf
return 0;
}其編譯過程及執行結果如下:
編譯:執行:
以下內容是在過程中檢視各檔案內容資訊:
[njs@njs]#cat no_buf1.txt
hello,w //寫入的7 個字元全部寫入到檔案中
[njs@njs]#cat no_buf2.txt
hello,w //寫入的7 個字元全部寫入到檔案中
[njs@njs]#cat l_buf.txt
hello //只有回車前的字元寫入
[njs@njs]#cat f_buf.txt //沒有任何內容寫入
執行過程完成後:
[njs@njs]#cat no_buf1.txt
hello,w //與原來內容一樣
[njs@njs]#cat no_buf2.txt
hello,w //與原來內容一樣
[njs@njs]#cat l_buf.txt
hello
world //因為呼叫了fclose()函式,重新整理了緩衝區,將world 寫入
[njs@njs]#cat f_buf.txt
hello
world //因為呼叫了fclose()函式,重新整理了緩衝區,將hello/nworld 都寫入
linux檔案緩衝區
一 緩衝區機制 根據應用程式對檔案的訪問方式,即是否存在緩衝區,對檔案的訪問可以分為帶緩衝區的操作和非緩衝區的檔案操作 緩衝區檔案操作 高階檔案系統,將在使用者空間中自動為正在使用的檔案開闢記憶體緩衝區。非緩衝區檔案系統 低階檔案系統,如果需要,只能由使用者在自己的程式中為每個檔案設定緩衝區。如果採...
檔案緩衝區
前段我把鍵盤丟了,今天我重新買了乙個鍵盤,新鍵盤拿到手後,舊鍵盤又被我找到了!我真是 現在呢,我兩個鍵盤它也沒多大用,於是我決定把新鍵盤送給我在北京的好盆友foreb。我現在有兩個送鍵盤的方案 1.我親自護送鍵盤,打車,買機票到北京,然後跑到他家,他在家的話,直接給他,不在家我再等等他,等他回來了給...
linux緩衝區解析
緩衝區是記憶體的一部分空間,用緩衝輸入輸出的資料。緩衝區又分為輸入緩衝區和輸出緩衝區。緩衝區又被稱為快取.主要的意義就是為了提高cpu的效率。輸入端。假如沒有緩衝區,我們要從磁碟中讀取資料,有幾個字元,cpu就要讀寫幾次,cpu是高速率的,而讀取是低速率的,這樣做會降低cpu的效率。相反如果將資料都...