readv(int fd,const struct iovec*iov,int iovcnt);
参数fd:打开的文件描述符,从fd中读取数据。
参数iov:结构体struct iovec数组,将fd中读取的数据保存到iov结构体数组中,保存的时候从下标为0开始。
参数iovcnt:iov结构体的大小。
struct iovce的数据结构如下:
struct iovec {
void *iov_base;
size_t iov_len;
}
调用readv()成功返回读到的字节数,若文件结束返回0。调用者必须对返回的字节数做检查,以验证读取的字节数是否符合要求,如数据不足以填充所有缓冲区,那么最后的一个缓冲区有可能只存有部分数据。
writev(int fd,const struct iovec*iov,int iovcnt);
参数fd:打开的文件描述符,将数据写入fd中。
参数iov:结构体struct iovec数组,将结构体中保存的数据写入fd中,写入的时候从下标为0开始。
参数iovcnt:iov结构体的大小。
下面是readv()writev()分散输入和集中输入从一个文件中读取数据,写入另一个文件的例程:
#include <fcntl.h>
#include <sys/stat.h>
#include <getopt.h>
#include <stdio.h>
#include <sys/uio.h>
#include "lib/tlpi_hdr.h"
#ifndef BUF_SIZE
#define BUF_SIZE 100
#endif
int main(int argc,char* argv[])
{
if(argc <3 || (strcmp(argv[1],"--help")==0))
{
usageErr("%s file\n",argv[1]);
}
struct iovec iov[3];
struct stat myStruct;
int x;
char str[BUF_SIZE];
ssize_t nRead,nWrite,nTotRequired;
nTotRequired = 0;
iov[0].iov_base = &myStruct;
iov[0].iov_len = sizeof(struct stat);
nTotRequired += iov[0].iov_len;
iov[1].iov_base = &x;
iov[1].iov_len = sizeof(int);
nTotRequired += iov[1].iov_len;
iov[2].iov_base = &str;
iov[2].iov_len = sizeof(str);
nTotRequired += iov[2].iov_len;
int fd = open(argv[1],O_RDONLY);
if(fd == -1)
errExit("open file:%s\n",argv[1]);
int wfd = open(argv[2],O_WRONLY|O_CREAT,0666);
if(wfd == -1)
errExit("open file:%s\n");
while((nRead = readv(fd,iov,3))>0)
{
nWrite = writev(wfd,iov,3);
if(nWrite == -1)
errExit("writev");
}
if(nRead == -1)
errExit("readv\n");
close(fd);
close(wfd);
exit(EXIT_SUCCESS);
}
如果结构体的大小不是结构体数组中所有数据长度的总长的倍数,那么最终拷贝的文件大小会大于源文件的大小。
preadv(int fd,const struct iovec*iov,int iovcnt,off_t offset);
参数fd:打开的文件描述符,从fd中读取数据。
参数iov:结构体struct iovec数组,将fd中读取的数据保存到iov结构体数组中,保存的时候从下标为0开始。
参数iovcnt:iov结构体的大小。
参数offset:文件的偏移量。
pwritev(int fd,const struct iovec*iov,int iovcnt);
参数fd:打开的文件描述符,将数据写入fd中。
参数iov:结构体struct iovec数组,将结构体中保存的数据写入fd中,写入的时候从下标为0开始。
参数iovcnt:iov结构体的大小。
参数offset:文件的偏移量。
preadv()和pwrite()函数在多线程中可以使用,每个线程指定读取和写入文件的某一块。