linux下分散输出和集中输入readv()和writev()

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()函数在多线程中可以使用,每个线程指定读取和写入文件的某一块。

猜你喜欢

转载自blog.csdn.net/len_yue_mo_fu/article/details/82976749