open,write,read与fopen,fwrite,fread的区别
open:系統(tǒng)調(diào)用,返回的是文件描述符,即文件句柄,是文件在文件描述副表里的索引。
fopen:C語言庫函數(shù),返回的是一個指向文件結(jié)構(gòu)的指針。fopen是ANSI C標準中的C語言庫函數(shù),在不同的操作系統(tǒng)中應該調(diào)用不同的內(nèi)核API,UNIX環(huán)境下,fopen是對open的封裝。
文件描述符是UNIX/Linux下的一個概念,linux環(huán)境下,一切設備皆是文件,一切設備皆是以文件的形式進行操作,如網(wǎng)絡套接字、硬件設備等。有關(guān)文件描述符和文件指針的區(qū)別可以參見博文:《文件描述符和文件指針的區(qū)別》。
設備文件不可以當成流式文件來處理,因此,只能使用open,而fopen只是用來操縱正規(guī)文件的,并且設置有緩沖,跟open還是有區(qū)別的。
?
open和fopen的區(qū)別在于:
?
1.緩沖文件系統(tǒng)
緩沖文件系統(tǒng)是借助于文件結(jié)構(gòu)體指針FILE *來對文件進行管理,通過文件指針對文件進行訪問,即可以讀寫字符、字符串、格式化數(shù)據(jù),也可以讀寫二進制數(shù)據(jù)。
緩沖文件系統(tǒng)特點:在內(nèi)存中開辟一個“緩沖區(qū)”,為程序里每一個文件使用,當執(zhí)行讀文件操作時,從磁盤文件將數(shù)據(jù)先讀入內(nèi)存“緩沖區(qū)”,裝滿后再從內(nèi)存“緩沖區(qū)”依次讀入接收的變量。執(zhí)行寫文件操作時,也是先將數(shù)據(jù)寫入內(nèi)存“緩沖區(qū)”,待內(nèi)存“緩沖區(qū)”裝滿后再寫入文件。由此可以看出,內(nèi)存“緩沖區(qū)”的大小,影響著實際操作外在的次數(shù),內(nèi)存“緩沖區(qū)”越大,則操作外存的次數(shù)就越少,執(zhí)行速度就越快,效率就越高。一般來說,文件“緩沖區(qū)”的大小跟機器是相關(guān)的。
緩沖文件系統(tǒng)的IO函數(shù)主要包括:fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等。
?
2.非緩沖文件系統(tǒng)
非緩沖文件系統(tǒng)依賴于操作系統(tǒng),通過操作系統(tǒng)的功能對文件進行讀寫,是系統(tǒng)級的輸入輸出,它不設文件結(jié)構(gòu)體指針,只能讀寫二進制文件(對于UNIX系統(tǒng)內(nèi)核而言,文本文件和二進制代碼文件并無區(qū)別),但效率高、速度快,由于ANSI標準不再包括非緩沖文件系統(tǒng),因此,在讀取正規(guī)的文件時,建議大家最好不要選擇它。
非緩沖文件系統(tǒng)的IO函數(shù)主要包括:open, close, read, write, getc, getchar, putc, putchar等。
?
舉個例子來說明open系列函數(shù)與fopen系列函數(shù)的效率問題:如果文件的大小是8k。
你如果用read/write,且只分配了2K的緩存,則要將此文件讀出需要做4次系統(tǒng)調(diào)用來實際從磁盤上讀出。如果你用fread/fwrite,則系統(tǒng)自動分配緩存,則讀出此文件只要一次系統(tǒng)調(diào)用從磁盤上讀出。也就是用read/write要讀4次磁盤,而用fread/fwrite則只要讀1次磁盤。效率比read/write要高4倍。如果程序?qū)?nèi)存有限制,則用read/write比較好。都用fread 和fwrite,它自動分配緩存,速度會很快,比自己來做要簡單。如果要處理一些特殊的文件,用read 和write,如套接口,管道之類的設備文件。
系統(tǒng)調(diào)用write的效率取決于你buffer的大小和你要寫入的總數(shù)量,如果buffer太小,你進入內(nèi)核空間的次數(shù)大增,效率就低下。而fwrite會替你做緩存,減少了實際出現(xiàn)的系統(tǒng)調(diào)用,所以效率比較高。
如果只調(diào)用一次(這種可能性比較小),這倆差不多,嚴格來說write要快一點點,因為實際上fwrite封裝了write,最后還是用write做真正的寫入文件系統(tǒng)工作,但是這其中的差別無所謂。
?
open和fopen最主要的區(qū)別在于fopen在用戶態(tài)下就有了緩存,在進行read和write時,減少了用戶態(tài)和內(nèi)核態(tài)的切換,而open則每次都需要進行內(nèi)核態(tài)和用戶態(tài)的切換,其表現(xiàn)為:如果順序訪問文件,fopen系統(tǒng)的函數(shù)要比直接調(diào)用open系統(tǒng)函數(shù)快,如果隨機訪問文件,open系列函數(shù)要比fopen系列函數(shù)快。
?
因此,open系列函數(shù)與fopen系列的區(qū)別可以簡單概括為:
| open系列函數(shù) | fopen系列函數(shù) |
| 一般用于打開設備文件(少數(shù)情況) | 一般用于打開普通文件(大多數(shù)情況) |
| 利用文件描述符操縱文件 | 利用文件指針操作文件 |
| open返回一個文件描述符 | fopen返回一個文件指針 |
| POSIX系統(tǒng)調(diào)用 | ANSI C庫函數(shù) |
| 低層次IO | 高層次IO,對open的擴展和封裝 |
| 只能在POSIX操作系統(tǒng)上移植 | 可移植到任何操作系統(tǒng) |
| 非緩沖IO | 緩沖IO |
| 只能讀取二進制或普通文本 | 可以讀取一個結(jié)構(gòu) |
| 可以指定要創(chuàng)建文件的訪問權(quán)限 | 不能指定要創(chuàng)建文件的訪問權(quán)限 |
fread返回的是一個FILE結(jié)構(gòu)指針
而read返回的是一個int的文件號
前者fopen/fread的實現(xiàn)是靠調(diào)用底層的open/read來實現(xiàn)的.
fopen/fread
是C標準的庫函數(shù),操作的對象是: file stream
open/read
是和操作系統(tǒng)有關(guān)的系統(tǒng)調(diào)用。操作的對象是: “file descriptor”
f是ANSI的C標準庫。后面的是UNIX下的系統(tǒng)調(diào)用。
帶f的帶有緩沖,是后面的衍生,
直接和硬件打交道,必須是后面的!
?
UNIX環(huán)境下的C?對二進制流文件的讀寫有兩套班子:1) fopen,fread,fwrite ; 2) open, read, write
這里簡單的介紹一下他們的區(qū)別。
1. fopen?系列是標準的C庫函數(shù);open系列是?POSIX?定義的,是UNIX系統(tǒng)里的system call。
也就是說,fopen系列更具有可移植性;而open系列只能用在?POSIX?的操作系統(tǒng)上。
2.?使用fopen?系列函數(shù)時要定義一個指代文件的對象,被稱為“文件句柄”(file handler),是一個結(jié)構(gòu)體;而open系列使用的是一個被稱為“文件描述符”?(file descriptor)的int型整數(shù)。
3. fopen?系列是級別較高的I/O,讀寫時使用緩沖;而open系列相對低層,更接近操作系統(tǒng),讀寫時沒有緩沖。由于能更多地與操作系統(tǒng)打交道,open系列可以訪問更改一些fopen系列無法訪問的信息,如查看文件的讀寫權(quán)限。這些額外的功能通常因系統(tǒng)而異。
4.?使用fopen系列函數(shù)需要"#include <sdtio.h>";使用open系列函數(shù)需要"#include <fcntl.h>"?,鏈接時要之用libc(-lc)
小結(jié):
總的來說,為了使程序獲得更好的可移植性,未到非得使用一些fopen系列無法實現(xiàn)的功能的情況下,fopen系列是首選。
?
read/write和fread/fwrite區(qū)別
1,fread是帶緩沖的,read不帶緩沖.
總結(jié)
以上是生活随笔為你收集整理的open,write,read与fopen,fwrite,fread的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STL内存分配
- 下一篇: Linux的内存理解