在Linux系统对文件执行输入或输出处理,有两种基本方式:一种是基于流的I/O方法,另一种是基于系统调用的I/O方法。
基于流的I/O调用,实际上是对系统调用进行了一次封装,这些函数调用自动使用缓冲区输出,使得程序能够尽可能少的使用系统调用,从而提高了程序的性能。因为从性能上来讲,系统调用是相当昂贵的,采取这种措施的确可以加快程序的执行速度。然而,这也引出了一些问题,程序员可能想让数据立即写出去。或者,程序员想在应用程序中混合使用系统调用I/O和基于流的I/O,他必须保证两者总是立即写出,否则,输出的最终结果势必将造成混乱。用来完成这个任务的函数是fflush()。该函数以一个指定的文件句柄为参数,它将对该文件句柄立即执行任何悬挂的I/O操作。无论什么时候,用户试图读取或者输入一个换行字符时,都将触发一个隐含的刷新操作。
当用户需要在一个较低的级别上和I/O子系统对话时,就得借助于系统调用I/O方法。通常,在处理文件或通用的I/O操作时,不必使用系统调用。然而,在处理网络套接字、设备、管道、FIFO或者其它特殊类型的通信时,系统调用I/O方法可能是你唯一的选择。另外值得注意的是,系统调用I/O函数不能确保将所有用户所需要的数据立即写出和读入,即使没有错误。一般情况下,在处理文件时观察不到这个延迟,但对于网络通信就很常见了,因为操作系统必须将数据分割成数据块用于数据传输。下面这个函数用户可以在程序中使用,确保所以数据都能被适当写出和读入。
int write_buffer(int fd, const void *buf, int count)
{
const void *pts = buf;
int status = 0, n;
if (count < 0) return (-1);
while (status != count)
{
n = write(fd, pts+status, count-status);
if (n < 0) return (n);
status += n;
}
return (status);
}
int read_buffer(int fd, void *buf, int count)
{
void *pts = buf;
int status = 0, n;
if (count < 0) return (-1);
while (status != count)
{
n = read(fd, pts+status, count-status);
if (n < 1) return n;
status += n;
}
return (status);
}