WRITE - Linux手册页
Linux程序员手册 第2部分
更新日期: 2019-10-10
名称
write-写入文件描述符
语法
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
说明
write()写入从buf开始的缓冲区到文件描述符fd引用的文件的计数字节。
例如,如果基础物理介质上的空间不足,或者遇到RLIMIT_FSIZE资源限制(请参阅setrlimit(2)),或者在调用之后被信号处理程序中断,则写入的字节数可能少于计数。写入少于计数字节。 (另请参见pipe(7)。)
对于可搜索文件(即,可以应用lseek(2)的文件,例如常规文件),将在文件偏移处进行写入,然后将文件偏移量增加实际写入的字节数。如果使用O_APPEND打开(2)文件,则在写入之前首先将文件偏移量设置为文件的末尾。文件偏移量的调整和写入操作是作为原子步骤执行的。
POSIX要求可以证明在返回write()之后发生的read(2)将返回新数据。请注意,并非所有文件系统都符合POSIX。
根据POSIX.1,如果count大于SSIZE_MAX,则结果是实现定义的;有关Linux上的上限,请参见注释。
返回值
成功后,将返回写入的字节数。发生错误时,将返回-1,并设置errno以指示错误原因。
请注意,成功的write()传输的字节数可能少于计数字节。发生这种部分写入的原因可能多种多样。例如,由于磁盘设备上没有足够的空间来写入所有请求的字节,或者是因为信号处理程序在传输了一些内容之后,但在此之前,对套接字,管道或类似对象的阻塞write()被中断了已经传输了所有请求的字节。在部分写入的情况下,调用方可以进行另一个write()调用以传输剩余的字节。随后的调用将传输更多字节或可能导致错误(例如,如果磁盘现在已满)。
如果count为零,并且fd指向常规文件,则如果检测到以下错误之一,则write()可能返回失败状态。如果未检测到错误或未执行错误检测,则将返回0,而不会引起任何其他影响。如果count为零,并且fd引用的文件不是常规文件,则不指定结果。
错误说明
- EAGAIN
- 文件描述符fd引用了套接字以外的文件,并被标记为非阻塞(O_NONBLOCK),并且写入将阻塞。有关O_NONBLOCK标志的更多详细信息,请参见open(2)。
- EAGAINor EWOULDBLOCK
- 文件描述符fd引用套接字,并被标记为非阻塞(O_NONBLOCK),并且写入将阻塞。 POSIX.1-2001允许在这种情况下返回任何一个错误,并且不需要这些常量具有相同的值,因此可移植应用程序应检查这两种可能性。
- EBADF
- fd不是有效的文件描述符,或者未打开以供写入。
- EDESTADDRREQ
- fd指的是尚未使用connect(2)设置对等地址的数据报套接字。
- EDQUOT
- 用户在包含fd所引用文件的文件系统上的磁盘块配额已用尽。
- EFAULT
- buf在您可访问的地址空间之外。
- EFBIG
- 试图写一个超出实现定义的最大文件大小或进程的文件大小限制的文件,或者试图写一个超出最大允许偏移量的位置。
- EINTR
- 在写入任何数据之前,该呼叫已被信号中断。参见signal(7)。
- EINVAL
- fd附加到不适合写入的对象上;或使用O_DIRECT标志打开了文件,并且buf中指定的地址,count中指定的值或文件偏移未正确对齐。
- EIO
- 修改索引节点时发生低级I / O错误。此错误可能与回写由较早的write()写入的数据有关,该数据可能已发布给同一文件上的不同文件描述符。从Linux 4.13开始,回写错误带来了可能由后续报告的错误。 write()请求,并将由随后的fsync(2)报告(无论是否也由write()报告)。联网文件系统上EIO的另一种原因是,在文件描述符上取消了咨询性锁定后,该锁定已丢失。有关更多详细信息,请参见fcntl(2)的"丢失的锁"部分。
- ENOSPC
- 包含fd引用的文件的设备没有存储数据的空间。
- EPERM
- 该操作被文件封条阻止;参见fcntl(2)。
- EPIPE
- fd连接到读数端关闭的管道或插座。发生这种情况时,写入过程还将收到SIGPIPE信号。 (因此,仅当程序捕获,阻止或忽略此信号时,才能看到写返回值。)
取决于连接到fd的对象,可能还会发生其他错误。
遵循规范
SVr4、4.3BSD,POSIX.1-2001。
在SVr4下,写操作可能会被中断并在任何时候返回EINTR,而不仅仅是在写任何数据之前。
备注
size_t和ssize_t类型分别是POSIX.1指定的无符号和有符号整数数据类型。
从write()成功返回并不能保证数据已提交到磁盘。在某些文件系统上,包括NFS,它甚至不能保证已为数据成功保留了空间。在这种情况下,某些错误可能会延迟到以后的write(),fsync(2)甚至close(2)。唯一确定的方法是在完成所有数据写入后调用fsync(2)。
如果在写入任何字节之前,信号处理程序中断了write(),则调用将失败,并显示错误EINTR;否则,调用将失败。如果在写入至少一个字节后中断,则调用成功,并返回写入的字节数。
在Linux上,write()(和类似的系统调用)将最多传输0x7ffff000(2,147,479,552)字节,并返回实际传输的字节数。 (在32位和64位系统上都是如此。)
使用直接I / O执行write()时返回的错误值并不表示整个写入都失败了。可能会写入部分数据,并且应将尝试执行write()的文件偏移量处的数据视为不一致。
BUGS
根据POSIX.1-2008 / SUSv4第XSI 2.9.7节("与常规文件操作的线程交互"):
- 当对常规文件或符号链接进行操作时,以下所有功能在POSIX.1-2008中指定的效果中,彼此之间应是原子的:...
随后列出的API中有write()和writev(2)。在线程(和进程)之间应该是原子性的影响包括文件偏移量的更新。但是,在版本3.14之前的Linux上,情况并非如此:如果两个共享打开文件描述的进程(请参阅open(2))同时执行write()(或writev(2)),则I / O操作不是更新文件偏移量的原子操作,其结果是两个进程输出的数据块可能(不正确)重叠。此问题已在Linux 3.14中修复。
另外参见
close(2),fcntl(2),fsync(2),ioctl(2),lseek(2),open(2),pwrite(2),read(2),select(2),writev(2), fwrite(3)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。