緩衝I/O與非緩衝I/O(fopen與open系列函式區別)
在程式中,對於檔案的讀寫,程式執行時間主要消耗在I/O上。與讀寫記憶體相比,讀寫硬碟上的檔案慢很多;每次讀取/寫入檔案的內容很少的話,那麼程式執行時間主要消耗在I/O上了。因此有了緩衝I/O和非緩衝I/O。
非緩衝I/O,每次對於檔案的操作,都要進行I/O操作。例如Linux的系統條用:
open, read, write, lseek, close。
它們依賴作業系統,沒有檔案結構體指標(把檔案當做二進位制檔案),直接對檔案進行操作,這些操作沒有經過緩衝區。例如寫一個檔案write,直接把內容寫到物理磁碟上了。優點是能迅速把內容寫到檔案中,在遇到突發事件時(例如斷電),內容不會丟失。缺點就是頻繁進行I/O操作,非常消耗CPU。
fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind
緩衝I/O,就是在記憶體中開闢了一塊緩衝區,對檔案的操作先存在了緩衝區,在“需要”的時候在寫到磁碟。一般來說,緩衝區越大,進行實際I/O就越少,效率越高。
它們依賴檔案結構體指標,可以讀寫字元、字串、格式化資料。
標準I/O的函式就是緩衝的I/O操作:
緩衝I/O有全緩衝和行緩衝:
全緩衝是在緩衝區填滿後才進行實際的I/O操作。在磁碟上的檔案常常由標準I/O庫函式實施全緩衝。
行緩衝是指在輸入或輸出中遇到換行符時,執行實際的I/O操作。
區別:
fopen系列函式是標準庫提供的,使用的是檔案結構體指標,把檔案當做流來處理。
open系列函式是系統條用,使用的是檔案描述符。
在Linux一切皆檔案,但是fopen操作的只是指普通檔案。裝置檔案不能當做流式檔案來處理的,只能使用open系列函式。
fopen使程序在使用者態下就有了緩衝區,不像open系列函式,每次都要進行系統條用,使用者態/核心態切換。