RIO的无缓冲的输入输出函数
ssize_t rio_readin(int fd, void *usrbuf, size_t n)
{
size_t nleft = n;
ssize_t nread;
char *bufp = usrbuf;
while(nleft>0){
if((nread = read(fd,bufp,nleft))<0){
if (errno == EINTR)
nread = 0;
else
return -1;
}
else if (nread == 0)
break;
nleft -= nread;
bufp += nread;
}
return (n-nleft);
}
rio_readin()是read()函数的扩展,自动处理了不足值。其实就是不断地调用read()函数,判断该函数的返回值,直到读取完毕碰到EOF。
在读CSAPP第十章系统级I/O时,书中提到无缓冲的输入输出函数rio_readn(int fd, void *usrbuf, size_t n)和rio_writen(int fd, void *usrbuf, size_t n)“对将二进制数据读写到网络和从网络读写二进制数据尤其有用”。
然后书中又提到“统计文本文件中的行数”这一问题引出了带缓冲的输入输出函数。rio_read(rio_t *rp, char *usrbuf, size_t n)是一个带缓冲的read函数,可以将rio_readn中的read函数换成rio_read函数就将可以处理不足值的不带缓冲的rio_readn(int fd, void *usrbuf, size_t n)函数转化成带有缓冲的。无缓冲的rio_readn可以用在网络中,带缓冲的rio_readn应该不可用在网络中(这是我的猜测,是不是有无缓冲是一个可不可以用在网络中的标准)。如果带缓冲的rio_readn不在网络情况下使用,则如果要读的字节数少于缓冲大小,则从缓冲中读取应读的字节数即可;如果要读的字节数大于缓冲容量,则需要再填充一次缓冲,从这个角度看,带缓冲的rio_readn没有比不带缓冲的rio_readn有任何优势(除非有其他方面的应用,才疏学浅,其他方面的应用我想不到,如果有,大牛可以提醒一下)。
缓冲的优势是将fd中的数据读入缓冲区,然后可以从缓冲区再读这些数据就成为了一个指针移动的操作。这对每次读取一个字节的一些应用非常有好处,因为如果每次读取一个字节都调用read()时,都要陷入内核。所以带缓冲的rio_read非常高效。