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()函數在多線程中可以使用,每個線程指定讀取和寫入文件的某一塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章