Vectored I/O

This article is about the I/O method. For the vector addressing type, see Gather-scatter (vector addressing).

In computing, vectored I/O, also known as scatter/gather I/O, is a method of input and output by which a single procedure-call sequentially writes data from multiple buffers to a single data stream or reads data from a data stream to multiple buffers. The buffers are given in a vector of buffers. Scatter/gather refers to the process of gathering data from, or scattering data into, the given set of buffers. Vectored I/O can operate synchronously or asynchronously. The main reasons for using vectored I/O are efficiency and convenience.

There are several usages for vectored I/O:

Standards bodies document the applicable functions readv[1] and writev[2] in POSIX 1003.1-2001 and the Single UNIX Specification version 2. The Windows API has analogous functions ReadFileScatter and WriteFileGather; however, unlike the POSIX functions, they require the alignment of each buffer on a memory page.[3] Windows Sockets provide separate WSASend and WSARecv functions without this requirement.

While working directly with a vector of buffers can be significantly harder than working with a single buffer, there are often higher-level APIs[4] for working efficiently that can mitigate the problem.

Examples

The following example prints "Hello Wikipedia Community!" to the standard output. Each word is saved into a single buffer and with only one call to writev(), all buffers are printed to the standard output.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <sys/types.h>
#include <unistd.h>
#include <sys/uio.h>
 
#define NUMBUFS 3
 
int
main(int argc, char *argv[])
{
	const char *buf1 = "Hello ";
	const char *buf2 = "Wikipedia ";
	const char *buf3 = "Community!\n";
 
	struct iovec bufs[NUMBUFS];
 
	bufs[0].iov_base = (void*) buf1;
	bufs[0].iov_len = strlen(buf1);
 
	bufs[1].iov_base = (void*) buf2;
	bufs[1].iov_len = strlen(buf2);
 
	bufs[2].iov_base = (void*) buf3;
	bufs[2].iov_len = strlen(buf3);
 
	if (-1 == writev(STDOUT_FILENO, bufs, NUMBUFS))
	{
		perror("writev()");
		exit(EXIT_FAILURE);
	}
 
	return 0;
}

References

  1. readv in the Single Unix Specification
  2. writev in the Single Unix Specification
  3. ReadFileScatter in MSDN Library
  4. Vstr the Vectored String API