当我们想要一次性对一个文件进行读、写多个非连续的缓冲区时,readv 和 writev 函数能够实现该功能。这两函数也称为散布读和聚集写。其定义如下:
/* 读、写多个非连续的缓冲区 */ /* * 函数功能:读取数据到多个非连续的缓冲区,或从多个非连续缓冲区写数据到文件; * 返回值:若成功则返回已读、写的字节数,若出错则返回-1; * 函数原型: */ #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); /* * 说明: * iovec的指针结构如下: */ struct iovec { void *iov_base; /* starting address of buffer */ size_t iov_len; /* size of buffer */ };
writev 以顺序 iov[0],iov[1] 至 iov[iovcnt-1] 从缓冲区中聚集输出数据。writev 返回输出的字节总数。readv 则将读入的数据按照上述同样顺序散布到缓冲区中,readv 总是先填满一个缓冲区,然后再填写下一个。readv 返回读到的总字节数。如果遇到文件结尾,已无数据可读,则返回0。
测试程序:
#include "apue.h" #include <sys/uio.h> #include <stdlib.h> int main(void) { struct iovec iov[2]; char *buf1 = (char *)malloc(5); char *buf2 = (char *)malloc(1024); memset(buf1, 0, 5); memset(buf2, 0, 1024); iov[0].iov_base = buf1; iov[1].iov_base = buf2; iov[0].iov_len = 5; iov[1].iov_len = 1024; ssize_t nread, nwrite; nread = readv(STDIN_FILENO, iov, 2); if(nread == -1) err_sys("readv error"); else { printf("readv:\n"); printf("buf1 is: %s\t length is: %d\n",buf1, strlen(buf1)); printf("buf2 is: %s\t length is: %d\n",buf2, strlen(buf2)); } printf("writev:\n"); nwrite = writev(STDOUT_FILENO, iov, 2); if(nwrite == -1) err_sys("writev error"); free(buf1); free(buf2); exit(0); }
readv writev and apue readv: buf1 is: readv length is: 5 buf2 is: writev and apue length is: 17 writev: readv writev and apue
《UNIX高级环境编程》