資源和工具
基礎(chǔ)知識
工程示例
x.1 read/write
read/write
read函數(shù)從打開的設備或文件中讀取數(shù)據(jù)。
#include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 返回值:成功返回讀取的字節(jié)數(shù),出錯返回-1并設置errno,如果在調(diào)read之前已到達文件末尾,則這次read返回0
參數(shù)count是請求讀取的字節(jié)數(shù),讀上來的數(shù)據(jù)保存在緩沖區(qū)buf中,同時文件的當前讀寫位置向后移。注意這個讀寫位置和使用C標準I/O庫時的讀寫位置有可能不同,這個讀寫位置是記在內(nèi)核中的,而使用C標準I/O庫時的讀寫位置是用戶空間I/O緩沖區(qū)中的位置。
fread就是通過read來實現(xiàn)的,fread是C語言的庫,而read是系統(tǒng)調(diào)用
但是差別在read每次讀的數(shù)據(jù)是調(diào)用者要求的大小,比如調(diào)用要求讀取10個字節(jié)數(shù)據(jù),read就會讀10個字節(jié)數(shù)據(jù)到數(shù)組中,而fread不一樣,為了加快讀的速度,fread每次都會讀比要求更多的數(shù)據(jù),然后放到緩沖區(qū)中,這樣下次再讀數(shù)據(jù)只需要到緩沖區(qū)中去取就可以了。
fread每次會讀取一個緩沖區(qū)大小的數(shù)據(jù),32位下一般是4096個字節(jié),相當于調(diào)用了read(fd,buf,4096)
比如需要讀取512個字節(jié)數(shù)據(jù),分4次讀取,調(diào)用read就是:
for(i=0; i<4; ++i)
read(fd,buf,128)
一共有4次系統(tǒng)調(diào)用
而fread一次就讀取了4096字節(jié)放到緩沖區(qū)了,所以省事了
比如用fgetc讀一個字節(jié),fgetc有可能從內(nèi)核中預讀1024個字節(jié)到I/O緩沖區(qū)中,再返回第一個字節(jié),這時該文件在內(nèi)核中記錄的讀寫位置是1024,而在FILE結(jié)構(gòu)體中記錄的讀寫位置是1。注意返回值類型是ssize_t,表示有符號的size_t,這樣既可以返回正的字節(jié)數(shù)、0(表示到達文件末尾)也可以返回負值-1(表示出錯)。read函數(shù)返回時,返回值說明了buf中前多少個字節(jié)是剛讀上來的。有些情況下,實際讀到的字節(jié)數(shù)(返回值)會小于請求讀的字節(jié)數(shù)count,例如:
讀常規(guī)文件時,在讀到count個字節(jié)之前已到達文件末尾。例如,距文件末尾還有30個字節(jié)而請求讀100個字節(jié),則read返回30,下次read將返回0。
從終端設備讀,通常以行為單位,讀到換行符就返回了。
從網(wǎng)絡讀,根據(jù)不同的傳輸層協(xié)議和內(nèi)核緩存機制,返回值可能小于請求的字節(jié)數(shù),后面socket編程部分會詳細講解。