都需要包含頭文件: <unistd.h>
read系統函數從打開的設備或文件中讀取數據,即將數據從外設上經過內核讀到用戶空間;write系統函數相反,向打開的設備或文件中寫入數據,即將數據從用戶空間(I/O緩沖)送到內核,然后刷到外設上。它們的函數原型如下:
ssize_t read(int fd, void *buf, size_t count);? ?
ssize_t為有符號整型,size_t為無符號整型。fd為相應的文件描述符;buf為用戶給定的數據緩沖區,該緩沖不是固定大小的,由count值決定其大小(用戶給定,字節數)。如 read( fd , “hello” , 5 ); 此時的void *buf為char *類型。即count為請求讀取的字節數(即buf的大小)。該函數的返回值為-1時,表示讀取數據失敗;返回值>0時,表示讀出的字節數;返回值等于0時,表示已經讀完了,因此沒有數據可讀了。
ssize_t write(int fd, const void *buf, size_t count);
buf為需要輸出的緩沖區,由用戶給定。cout為最大輸出字節數(buf的大小,字節數)。返回值為-1時,表示寫入失敗;>=0時,表示寫入的字節數。
以上兩個緩沖區buf都是用戶空間的地址,但是與I/O緩沖區不一樣,后者是規定的,前者是用戶自己指定的。
思考:利用read、write每次讀或寫1個Byte與利用gets和puts每次讀或寫1個Byte哪一種方式速度更快?
read和write函數為Linux系統函數,其緩沖區由用戶來維護,即用戶指定其大小,從而每次要將用戶空間的數據送到內核或從內核送到用戶空間的數據大小是由用戶來規定的(count);而gets和puts為C庫函數,其I/O緩沖區由庫函數自己維護,大小為8Byte,因此平均上,每傳送8個Byte的數據量才會操作一次內核。綜上,以上兩者在讀寫數據時,顯然read、write函數每次從用戶空間讀1Byte數據是就會操作一次內核(系統調用)(,開銷更大,速度會更慢。而puts和gets函數速度更快。 當然,用戶可以指定read和write的count參數,來增大其緩沖區大小,從而提高其讀寫速度,使其比puts和gets更快(對大文件來說,效果更加明顯)。
下面舉例說明read和write的用法:
?
//將一個文件(english.txt)的內容讀到另一個文件(writefile.txt)
[root@localhost work]# vim rdwr.c
[root@localhost work]# ls
english.txt? rdwr.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>int main( )
{int fd;fd = open("english.txt",O_RDONLY); //以只讀方式打開printf("open readfile's fd=%d\n",fd);if( fd == -1 ){perror(" open english.txt " );exit(1);}int fd1;char buff[1024] = { 0 }; //定義一個緩沖區fd1 = read( fd,buff,sizeof(buff) ); //將數據讀出到緩沖區printf("read readfile's fd1=%d\n",fd1);if( fd1 == -1 ){perror(" read english.txt " );exit(1);}int fd2;fd2 = open( "writefile.txt" ,O_WRONLY | O_CREAT | O_EXCL,0664); //創建一個寫文件,并以只寫的方式打開,如果文件創建的文件存在,則結束printf("open writefile's fd2=%d\n",fd2);if ( fd2 == -1 ){perror( "creat file" );exit(1);}int ret;while( fd1 ){ret = write( fd2,buff,fd1); //將讀出的數據寫進另一個新文件if( ret == -1 ){perror( "write file");exit(1);}fd1 = read( fd,buff,1024); //再次讀數據到緩沖區if( fd1 == -1 ){perror(" read english.txt " );exit(1);}}int qw1;int qw2;qw1=close(fd); //關閉文件if( ret == -1 ){perror( "close readfile");exit(1);}qw2=close(fd2);if( ret == -1 ){perror( "close writefile");exit(1);}return 0;
}
?[root@localhost work]# gcc -pipe -pedantic -Wall -ggdb3 rdwr.c -o rdwr
[root@localhost work]# ./rdwr
open readfile's fd=3
read readfile's fd1=1024
open writefile's fd2=4
[root@localhost work]# ls
english.txt? rdwr? rdwr.c? writefile.txt
[root@localhost work]# ll writefile.txt
-rwxrwxrwx. 1 root root 109055 Mar 19 11:39 writefile.txt
[root@localhost work]# ll english.txt
-rwxrwxrwx. 1 root root 109055 Mar 19 10:30 english.txt? //兩文件大小一樣