SENDFILE - Linux手册页

时间:2019-08-20 17:59:19  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2017-09-15

名称

sendfile-在文件描述符之间传输数据

语法

#包括

ssize_t sendfile(int out_fd,int in_fd,off_t * offset,size_t count);

说明

sendfile()在一个文件描述符和另一个文件描述符之间复制数据。由于此复制是在内核中完成的,因此sendfile()比read(2)和write(2)的组合更有效,后者需要在用户空间之间来回传输数据。

in_fd应该是为读取而打开的文件描述符,而out_fd应该是为写入而打开的描述符。

如果offset不为NULL,则它指向保存文件offset的变量,sendfile()将开始从该变量中读取in_fd中的数据。当sendfile()返回时,此变量将设置为读取的最后一个字节之后的字节的偏移量。如果offset不为NULL,则sendfile()不会修改in_fd的文件偏移;否则,将调整文件偏移量以反映从in_fd读取的字节数。

如果offset为NULL,则将从in_fd读取数据,从文件偏移开始,并且文件偏移将通过调用进行更新。

count是要在文件描述符之间复制的字节数。

in_fd参数必须与支持类似mmap(2)的操作的文件相对应(即,它不能是套接字)。

在2.6.33之前的Linux内核中,out_fd必须引用套接字。从Linux 2.6.33开始,它可以是任何文件。如果它是常规文件,则sendfile()会适当更改文件偏移量。

返回值

如果传输成功,则返回写入out_fd的字节数。请注意,成功调用sendfile()可能会写入少于请求的字节数。如果有未发送的字节,则呼叫者应准备重试呼叫。另请参阅注释。

如果出错,则返回-1,并正确设置errno。

错误说明

EAGAIN
已使用O_NONBLOCK选择了非阻塞I / O,写入将被阻塞。
EBADF
输入文件未打开以供读取或输出文件未打开以供写入。
EFAULT
地址错误。
EINVAL
描述符无效或被锁定,或者in_fd无法使用类似mmap(2)的操作,或者count为负。
EINVAL
out_fd设置了O_APPEND标志。 sendfile()当前不支持此功能。
EIO
从in_fd读取时发生未指定的错误。
ENOMEM
内存不足,无法从in_fd中读取。
EOVERFLOW
如果count太大,则该操作将导致超出输入文件或输出文件的最大大小。
ESPIPE
offset不是NULL,但是输入文件不可搜索。

版本

sendfile()首次出现在Linux 2.2中。自glibc 2.1起就存在include文件。

遵循规范

POSIX.1-2001或其他标准中均未指定。

其他UNIX系统使用不同的语义和原型来实现sendfile()。不应在可移植程序中使用它。

备注

sendfile()将最多传输0x7ffff000(2,147,479,552)字节,返回实际传输的字节数。 (在32位和64位系统上都是如此。)

如果计划使用sendfile()将文件发送到TCP套接字,但是需要在文件内容之前发送一些头数据,则发现使用tcp(7)中所述的TCP_CORK选项对最小化很有用。数据包数量和性能调整。

在Linux 2.4和更早版本中,out_fd也可以引用常规文件。这种可能性在Linux 2.6.x内核系列中消失了,但在Linux 2.6.33中得到了恢复。

最初的Linux sendfile()系统调用未设计为处理大文件偏移量。因此,Linux 2.4添加了sendfile64(),其offset参数的类型更大。 glibc sendfile()包装函数透明地处理内核差异。

如果sendfile()因EINVAL或ENOSYS失败,应用程序可能希望退回到read(2)/ write(2)。

如果out_fd引用支持零拷贝的套接字或管道,则调用者必须确保in_fd引用的文件的传输部分保持不变,直到out_fd另一端的读取器使用了传输的数据为止。

特定于Linux的splice(2)调用支持在任意文件描述符之间传输数据,只要其中一个(或两者)都是管道即可。

另外参见

copy_file_range(2),mmap(2),open(2),socket(2),splice(2)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/