Записать последовательность байт в файл
#include <unistd.h>ssize_t write( int fildes,const void *buf,size_t nbytes );
libc
Функция write() записывает nbytes байт в файл, дескриптор которого передан в fildes, из области памяти, указатель на которую передан в buf.
Если nbytes равен нулю, write() возвращает ноль, и не выполняет других действий.
В обычном файле (или любом другом файле, в котором возможен поиск с последовательным смещением отступа от начала), если не установлен флаг O_APPEND
, write() начинает работу с позиции, которую определяет отступ, соответствующий дескриптору fildes. Если флаг O_APPEND
установлен, отступ установлен в конце файла до начала операции записии. До успешного возврата из write()
отступ файла увеличивается на число байт, которые были записаны. В обычном файле, если новый полученный отступ больше, чем длина файла, длина файла преобразуется к значению отступа.
Обратите внимание, что вызов write() игнорирует рекомендованные блокировки, которые могли быть установлены функцией fcntl(). |
Для файла, в котором невозможен поиск с последовательным смещением отступа от начала, write() начинает работать с текущей позиции.
Если write() требует больше байт для записи, чем существует (например, все блоки на диске уже выделены), то записывает столько байт, сколько было доступно. Например, если есть место только для 80
байт для записи, то для записи 512
байт будет возвращено только 80
. Следующая запись ненулевого количества байт приведет к возврату ошибки (за исключением случаев, указанных ниже).
Когда write() завершается успешно, ее возвращаемое значение это число байт, которые были в действительности записаны в файл. Это число никогда не превышает значение nbytes, но может быть меньше при обстоятельствах, описанных ниже.
Если write() прервана сигналом до записи любого количества байт, она возвращает -1
, а переменной errno устанавливается значение EINTR
. Однако, если a write() была прервана сигналом после того, как какая-то часть данных была записана, она возвращает количество записанных байт. Если значение nbytes выше чем INT_MAX
, write() возвращает -1
и устанавливает переменной errno значение EINVAL
(см. <limits.h>
).
Запрос записи в менеджер каналов pipe (или FIFO) обрабатывается аналогично записи в обычный файл, со следующими исключениями:
PIPE_BUF
байт или меньше не перемешиваются данными от других процессов, которые могут записывать в тот же менеджер каналов. Запись большего количество байт может привести к перемешиванию данных в произвольных местах, с данными других процессов, вне зависимости от того, был ли установлен флаг O_NONBLOC
.
O_NONBLOCK
флаг не установлен, запрос записи может привести процесс к блокировки, но при успешном завершении он возвращает nbytes.
O_NONBLOCK
флаг установлен, запрос записи может быть обработан по разному: PIPE_BUF
bytes или меньше либо успешно завершится и вернет nbytes байт, или вернет -1
и установит переменной errno значение EAGAIN
. Если вызвать write() с nbytes больше чем PIPE_BUF
, функция либо отработает корректно и вернет количество записанных байт, либо не запишет данных, вернув -1
и установив переменной errno значение EAGAIN
. Также если nbytes выше чем PIPE_BUF
, и все данные до этого записаны в менеджер каналов уже были прочитаны (то есть менеджер каналов pipe не обрабатывае данных), write() запишет как минимум PIPE_BUF
байт.
При попытке записать в файл (не в менеджер каналов pipe и FIFO), который поддерживает неблокирующую запись и не может принять данные мгновенно:
O_NONBLOCK
флаг не установлен, write() блокирует процесс до момента, когда данные могут быть приняты. O_NONBLOCK
флаг установлен, write() не блокирует процесс. Если какие-то данные не могут быть записаны без блокировки процесса, write() записывает только принятые данные и возвращает количество записанных байт. В противном случае, функция вернет -1
и установит переменной errno значение EAGAIN
. Если write() вызвана для дескриптора файла, отступ которого за пределами конца файла, файл будет продлен до текущего отступа с вставкой недостающих байт, заполненных нулями. Это полезная техника для предварительного увеличения размера файла.
Если write() завершилась с успехом, поля файла st_ctime и st_mtime помечаются для обновления.
Число записанных байт данных. Если возникла ошибка функция возвращает -1
, код ошибки записывается в errno.
O_NONBLOCK
установлен для файлового дескриптора, процесс будет задержан при операции записи. 0
, а начальная позиция больше или равна максимальному смещению, установленному в описании открытого файла, связанного с fildes. TOSTOP
установлен, процесс не игнорирует и не блокирует SIGTTOU
, а группа процессов процесса потеряна. SIGPIPE
также был послан процессу. SOCK_STREAM
, сигнал SIGPIPE
доставлен вызывающему процессу. #include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>char buffer[] = { "A text record to be written" };int main( void ){int fd;int size_written;/* open a file for output *//* replace existing file if it exists */fd = creat( "myfile.dat", S_IRUSR | S_IWUSR );/* write the text */size_written = write( fd, buffer, sizeof( buffer ) );/* test for error */if ( size_written != sizeof( buffer ) ){perror( "Error writing myfile.dat" );return (EXIT_FAILURE);}/* close the file */close( fd );return (EXIT_SUCCESS);}
POSIX 1003.1 X/Open Systems Interfaces Extension
close(), creat(), dup(), dup2(), errno, fcntl(), lseek(), open(), pipe(), read(), readv(), select(), writev()
Предыдущий раздел: Описание API системной библиотеки