都需要包含头文件:
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
#include
#include
#include
#include
#include
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 //两文件大小一样