四个读写函数

 

四个读写函数

一、readvwritev函数

功能:用于在一次函数调用中读写多个非连续缓冲区。有时也将这两个函数成为散布读(scatter read)和聚集写(gather write)。

#include <sys/uio.h>

 

ssize_t readv(int filedes, const struct iovec *iov , int iovcnt);

 

ssize_t writev(int filedes, const struct iovec*iov, int iovcnt);

Both return: number of bytes read or written, -1 on error

这两个参数的第二个参数是指向iovec结构的指针。

struct iovec {
     void   *iov_base;   /* starting address of buffer */
     size_t  iov_len;    /* size of buffer */
   };

iov数组中的元素由iovcnt说明。其最大值受限于IOV_MAX

writev以顺序iov[0],iov[1]iov[iovcnt-1]从缓冲区中聚集输出数据。Writev返回输出的字节总数,通常它应等于所有缓冲区长度的总和。

readv则将读入的数据按上述同样的顺序散布到缓冲区中。readv总是先填满一个缓冲区,然后再填写下一个。readv返回读到的总字节数。如果遇到文件尾,已无数据可读,则返回0

 

对于少量数据,使用writev/readv的固定开销大于得益。随着复制数据的增加,程序中复制缓冲区的开销也会增多。这时候,writev/readv这种替代方法就会有更大的吸引力。

 

二、readnwriten函数

功能:读写指定的N字节数据。

背景:

管道、FIFO以及某些设备,特别是终端、网络和STREAMS设备有下列两种性质:

1、   一次read操作所返回的数据可能少于所要求的数据,即使还没有达到文件尾端,也可能是这样。

2、   一次write操作的返回值也可能少于指定输出的字节数。

在读写磁盘文件时从未遇到过这样的情况,除非文件系统用完了空间,或者我们接近了配额限制,而不能将要求的数据全部写出。

 

#include "apue.h"

 

ssize_t readn(int filedes, void *buf, size_t nbytes);

 

ssize_t writen(int filedes, void *buf, size_t nbytes);

Both return: number of bytes read or written, -1 on error

在要将数据写到上面提到的文件类型上时,就可以用writen。但是只有当事先知道要接收的数量时,才可以使用readn(通常只调用read接收来自这些设备上的数据)。

示例:readnwriten函数的实现

#include "apue.h"
 
ssize_t             /* Read "n" bytes from a descriptor */
readn(int fd, void *ptr, size_t n)
{
    size_t       nleft;
    ssize_t      nread;
 
    nleft = n;
    while (nleft > 0) {
        if ((nread = read(fd, ptr, nleft)) < 0) {
            if (nleft == n)
                return(-1); /* error, return -1 */
            else
                break;      /* error, return amount read so far */
        } else if (nread == 0) {
            break;          /* EOF */
        }
        nleft -= nread;
        ptr += nread;
    }
    return(n - nleft);      /* return >= 0 */
}
 
ssize_t             /* Write "n" bytes to a descriptor */
writen(int fd, const void *ptr, size_t n)
{
    size_t      nleft;
    ssize_t     nwritten;
 
    nleft = n;
    while (nleft > 0) {
        if ((nwritten = write(fd, ptr, nleft)) < 0) {
            if (nleft == n)
                return(-1); /* error, return -1 */
            else
                break;      /* error, return amount written so far */
        } else if (nwritten == 0) {
            break;
        }
        nleft -= nwritten;
        ptr   += nwritten;
    }
    return(n - nleft);      /* return >= 0 */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值