1. 程式人生 > >linux下分散輸出和集中輸入readv()和writev()

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()函式在多執行緒中可以使用,每個執行緒指定讀取和寫入檔案的某一塊。