3.2 read()和write()函数
对文件描述字进行基本输入输出操作的函数是read()和write()。
#include <unistd.h>
ssize_t read (int filedes, void * buffer, size_t nbytes);
ssize_t write (int filedes, const void * buffer, size_t nbytes);
read()从已打开的、与文件描述字filedes相连的文件中读至多nbytes个字节的数据放到buffer所指缓冲区中。它的正常返回值是实际读入的字节数,若在实际读入字节之前便遇到文件尾,其返回值为0。read()是所有读流的函数(如fgets()等)的低级原语。
数据类型ssize_t与size_t类似,UNIX系统也用它表示在一次操作中可以读写的块大小。不过与size_t不同的是,它是一个有符号整型以便能够表示错误情形的返回值。read()返回的实际读入字节数在以下几种情况下可能小于nbytes:
当读普通文件且在还未读够所请求的字节数便遇到了文件尾时。例如,当文件中只剩下30个字节便到达文件尾,而我们却企图读100个字节时,read()将返回30。下一次再调用read(),它将返回0指出文件结束。
当所读的文件对应于终端设备时,通常每次至多只读一行(在第9章将看到如何改变这种约定)。
当从网络读时,网络的内部缓冲可能导致读入的字节数少于所请求的字节数。
当被信号中断时(7.9.3节),若已读入若干字节,则返回已读的字节数;否则返回–1,并置errno为EINTR。
对于普通文件或其他可以定位的文件,read()从文件的当前位置开始读数据;在成功返回之前,文件位置增加实际已读的字节数。
read()调用成功的返回值大于等于0,遇到文件尾返回0(除非nbytes之值为0)。若在文件结束时继续调用read(),它将仍然返回0并且无其他动作。
write()将buffer的前nbytes个字节写到与描述字filedes相连的文件。buffer中的数据不必是字符串,空字符同其他字符一样写出。
write()的返回值是实际写出的字节数,正常情况下它等于nbytes,但也可能小于nbytes(例如,被写的物理介质满时)。
例3-1 程序3-1是open()、close()、read()和write()的示例程序,它是用这些低级I/O函数实现连接两个文件的另一个版本。
由于每次调用read()和write()都会使得系统访问磁盘,因此在读写时指定较大的缓冲很重要,否则程序的运行效率将会很低。这个例子中指定缓冲大小为1024字节,建议你指定不同的缓冲大小来运行这个程序,从中仔细体会缓冲大小对效率的影响。