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