一、read函數
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緩沖區中的位置。比如用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程式設計部分會詳細講解。
二、write函數
write函數向打開的裝置或檔案中寫資料。
ssize_t write(int fd, const void *buf, size_t count);
傳回值:成功傳回寫入的位元組數,出錯傳回-1并設定errno
簡單例子:(通過read和write函數實作檔案的拷貝)
int main(int argc,char *argv[])
{
char buf[SIZE];
int fd_src,fd_dest,len;
if(argc < 3)
printf("./mycp src dest\n");
exit(1);
}
umask(0);
fd_src = open(argv[1],O_RDONLY);
fd_dest = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
/*
*成功傳回讀到的位元組數
*讀失敗傳回 -1
*讀到檔案末尾傳回0
*/
while((len = read(fd_src, buf, sizeof(buf))) > 0)
write(fd_dest, buf, len);
close(fd_src);
close(fd_dest);
return 0;