一:緩衝區機制
根據應用程式對檔案的訪問方式,即是否存在緩衝區,對檔案的訪問可以分為帶緩衝區的操作和非緩衝區的檔案操作:
緩衝區檔案操作:高階檔案系統,將在使用者空間中自動為正在使用的檔案開闢記憶體緩衝區。
非緩衝區檔案系統:低階檔案系統,如果需要,只能由使用者在自己的程式中為每個檔案設定緩衝區。
如果採用非緩衝的檔案訪問方式,每次對該檔案進行一次讀寫操作時,都需要使用讀寫檔案系統掉用來處理該操作,因此,如果使用者需要訪問某個磁碟檔案,則每訪問一次都要執行一次系統呼叫,執行一次系統呼叫將涉及到cpu
狀態的切換,即從使用者空間切換到核心空間,實現上下文的切換,這將損耗一定的
cpu時間,頻繁的磁碟訪問對程式的執行效率造成很大的影響。
ansi標準
c庫函式建立在底層系統呼叫之上,即
c函式庫檔案訪問函式的實現中使用了低階檔案
i/o系統呼叫,
ansi標準c
庫中的檔案處理函式為了減少使用系統呼叫的次數,提高效率,根據應用的不同,採用緩衝區機制,這樣,在對磁碟檔案進行讀操作時,可以一次從檔案中讀出大量的資料到緩衝區中,以後對這部風的訪問就不需要在使用系統呼叫了,即只需要少量的
cpu狀態切換。在對檔案進行寫操作時,可以先將內容存在緩衝區,待檔案寫滿後,或者確實需要更新時在呼叫系統呼叫將檔案一次寫入到磁碟中。
二:緩衝區型別
標準 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 //真實大小
重新整理(flush
)操作即標準
i/o
緩衝區的寫操作。它可以由系統自動完成(當填滿乙個緩
沖區時)或者呼叫函式 fflush()
或 flush()
實現。
2,行緩衝區:在這種情況下,當在輸入和輸出中遇到換行符時,標準 i/o
庫執行
i/o系統呼叫操作。當流涉及乙個終端時(例如標準輸入和標準輸出),使用行緩衝區。因為標準i/o
庫收集的每行的緩衝區長度是固定的,只要填滿了緩衝區,即使還沒有遇到換行符,也將執行
i/o
系統呼叫操作。預設行緩衝區大小為
128
位元組。
3,無緩衝區:標準 i/o
庫不對字元進行快取。如果用標準
i/o
函式寫若干字元到不帶
緩衝區的流中,則相當於用 write
系統呼叫函式將這些字元寫至相關聯的開啟檔案。標準出錯流
stderr
通常是不帶緩衝區的,這使得出錯資訊能夠盡快地顯示出來。
對於標準輸入輸出裝置,ansi c
要求具有以下緩衝區特徵:
l 標準輸入和標準輸出裝置:當且僅當不涉及互動作用裝置時,標準輸入流和標準輸
出流才是全緩衝區的。
l 標準錯誤輸出裝置:標準出錯決不會是全緩衝區的。
對於任何乙個給定的流,可以呼叫 setbuf()
和 setvbuf()
函式更改其緩衝區型別。1,
名稱::
setbuf
功能:更改檔案流的緩衝區位置
標頭檔案:
#inlcude
函式原形:
void setbuf (file * restrict stream, char * restrict buf)
引數:stream 要操作的流物件
buf 指定的緩衝區
返回值:
若成功則返回0,若出錯則為非0
此函式第乙個引數為要操作的流物件,第二個引數 buf
必須指向乙個長度為
bufsiz
的緩衝區。如果將 buf
設定為
null
,則關閉緩衝區。
如果執行成功,將返回 0
,否則返回非
0 值。
2,名稱::
setvbuf
功能:更改檔案流的緩衝區位置
標頭檔案:
#inlcude
函式原形:
int setvbuf (file * restrict stream, char *restrict buf, int modes,size_t n)
引數:stream 要操作的流物件
buf 指定的緩衝區
mode 緩衝區型別
n buf的大小
返回值:
若成功則返回0,若出錯則為非0
/* make stream use buffering mode mode. if buf is not null, use n bytes of it for buffering;else allocate an internal buffer n bytes long. */
此函式第乙個引數為要操作的流物件;第二個引數 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
大小寫檔案的例項程式。其源**如下:
no_buf1.txt
內容press enter to continue!
test setvbuf(no buf)!check no_buf2.txt//在按回車鍵前需要先檢視當前目錄下的
no_buf2.txt
內容because line buf, only before enter data write
press enter to continue!
test setvbuf(line buf)!check l_buf.txt, because line buf ,only data before enter send to file
press enter to continue! //在按回車鍵前需要先檢視當前目錄下的
l_buf.txt 內容
test setbuf(full buf)!check f_buf.txt
press enter to continue! //在按回車鍵前需要先檢視當前目錄下的
f_buf.txt
內容7
個字元全部寫入到檔案中
7 個字元全部寫入到檔案中
fclose()
函式,重新整理了緩衝區,將
world
寫入fclose()
函式,重新整理了緩衝區,將
hello/nworld
都寫入
檔案緩衝區
前段我把鍵盤丟了,今天我重新買了乙個鍵盤,新鍵盤拿到手後,舊鍵盤又被我找到了!我真是 現在呢,我兩個鍵盤它也沒多大用,於是我決定把新鍵盤送給我在北京的好盆友foreb。我現在有兩個送鍵盤的方案 1.我親自護送鍵盤,打車,買機票到北京,然後跑到他家,他在家的話,直接給他,不在家我再等等他,等他回來了給...
Linux檔案緩衝區詳解
華清遠見嵌入式學院講師。a 緩衝區機制 根據應用程式對檔案的訪問方式,即是否存在緩衝區,對檔案的訪問可以分為帶緩衝區的操作和非緩衝區的檔案操作 a 帶緩衝區檔案操作 高階標準檔案i o操作,將會在使用者空間中自動為正在使用的檔案開闢記憶體緩衝區。b 非緩衝區檔案操作 低階檔案i o操作,讀寫檔案時,...
linux緩衝區解析
緩衝區是記憶體的一部分空間,用緩衝輸入輸出的資料。緩衝區又分為輸入緩衝區和輸出緩衝區。緩衝區又被稱為快取.主要的意義就是為了提高cpu的效率。輸入端。假如沒有緩衝區,我們要從磁碟中讀取資料,有幾個字元,cpu就要讀寫幾次,cpu是高速率的,而讀取是低速率的,這樣做會降低cpu的效率。相反如果將資料都...