linux下fread/read和fwrite/write

1,fread是帶緩衝的,read不帶緩衝.

2,fopen是標準c裏定義的,open是POSIX中定義的.

3,fread可以讀一個結構.read在linux/unix中讀二進制與普通文件沒有區別.

4,fopen不能指定要創建文件的權限.open可以指定權限.

5,fopen返回指針,open返回文件描述符(整數).

6,linux/unix中任何設備都是文件,都可以用open,read.

如果文件的大小是8k。

你如果用read/write,且只分配了2k的緩存,則要將此文件讀出需要做4次系統調用來實際從磁盤上讀出。

如果你用fread/fwrite,則系統自動分配緩存,則讀出此文件只要一次系統調用從磁盤上讀出。

也就是用read/write要讀4次磁盤,而用fread/fwrite則只要讀1次磁盤。效率比read/write要高4倍。

如果程序對內存有限制,則用read/write比較好。

都用fread 和fwrite,它自動分配緩存,速度會很快,比自己來做要簡單。如果要處理一些特殊的描述符,用read 和write,如套接口,管道之類的

系統調用write的效率取決於你buf的大小和你要寫入的總數量,如果buf太小,你進入內核空間的次數大增,效率就低下。而fwrite會替你做緩存,減少了實際出現的系統調用,所以效率比較高。

如果只調用一次(可能嗎?),這倆差不多,嚴格來說write要快一點點(因爲實際上fwrite最後還是用了write做真正的寫入文件系統工作),但是這其中的差別無所謂。

============ 

read/write 系統調用

read函數從打開的設備或文件中讀取數據。
#include <unistd.h>  ssize_t read(int fd, void *buf, size_t count); 返回值:成功返回讀取的字節數,出錯返回-1並設置errno,如果在調read之前已到達文件末尾,則這次read返回0
參數count是請求讀取的字節數,讀上來的數據保存在緩衝區buf中,同時文件的當前讀寫位置向後移。注意這個讀寫位置和使用C標準I/O庫時的讀寫位置有可能不同,這個讀寫位置是記在內核中的,而使用C標準I/O庫時的讀寫位置是用戶空間I/O緩衝區中的位置

fread就是通過read來實現的,fread是C語言的庫,而read是系統調用
但是差別在read每次讀的數據是調用者要求的大小,比如調用要求讀取10個字節數據,read就會讀10個字節數據到數組中,而fread不一樣,爲了加快讀的速度,fread每次都會讀比要求更多的數據,然後放到緩衝區中,這樣下次再讀數據只需要到緩衝區中去取就可以了。

fread每次會讀取一個緩衝區大小的數據,32位下一般是4096個字節,相當於調用了read(fd,buf,4096)

比如需要讀取512個字節數據,分4次讀取,調用read就是:
for(i=0; i<4; ++i)
read(fd,buf,128)
一共有4次系統調用

而fread一次就讀取了4096字節放到緩衝區了,所以省事了


比如用fgetc讀一個字節,fgetc有可能從內核中預讀1024個字節到I/O緩衝區中,再返回第一個字節,這時該文件在內核中記錄的讀寫位置是1024,而在FILE結構體中記錄的讀寫位置是1。注意返回值類型是ssize_t,表示有符號的size_t,這樣既可以返回正的字節數、0(表示到達文件末尾)也可以返回負值-1(表示出錯)。read函數返回時,返回值說明了buf中前多少個字節是剛讀上來的。有些情況下,實際讀到的字節數(返回值)會小於請求讀的字節數count,例如:
  • 讀常規文件時,在讀到count個字節之前已到達文件末尾。例如,距文件末尾還有30個字節而請求讀100個字節,則read返回30,下次read將返回0。

  • 從終端設備讀,通常以行爲單位,讀到換行符就返回了。

  • 從網絡讀,根據不同的傳輸層協議和內核緩存機制,返回值可能小於請求的字節數,後面socket編程部分會詳細講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章