SENDFILE - Linux手册页
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/。