Node:Writing files at a low level, Next:Finding file positions at a low level, Previous:Reading files at a low level, Up:Low-level file routines
Writing files at a low level
You can write a block of information to a file with the write
function, which is called by all high-level file writing routines, such as fwrite
. It takes three parameters. The first is the file descriptor of the file you wish to write to. The second is a buffer, of type void *
, that contains the data you wish to write. (It can be an array of bytes, but need not be a text string. Null characters in the data are treated in the same way as other characters.) The third parameter is of type size_t
, and specifies the number of bytes that are to be written.
The return value of this function is of type ssize_t
, and indicates the number of bytes actually written. This may be the same as the third parameter (the number of bytes to be written), but may be less; you should always call write
in a loop, and iterate the loop until all data has been written. If there is an error, write
returns -1. The write
function will return the following error codes in the system variable errno
, as well as the usual file name errors. (See Usual file name errors.)
EBADF
- The file descriptor specified is invalid, or is not open for writing.
EFBIG
- If the data were written, the file written to would become too large.
EIO
- There has been a hardware error.
EINTR
- The write operation was temporarily interrupted.
ENOSPC
- The device containing the file is full.
In addition to the error codes above, write
can return some error codes that are mainly of interest to advanced C programmers. If write
fails, you should check errno
to see if the error was EINTR
; if it was, you should repeat the write
call each time.
Even though low-level file routines do not use buffering, and once you call write
, your data can be read from the file immediately, it may take up to a minute before your data is physically written to disk. You can call the fsync
routine (see below) to ensure that all data is written to the file; this usage is roughly analogous to the high-level file routine fflush
.
The fsync
routine takes a single parameter, the file descriptor to synchronise. It does not return a value until all data has been written. If no error occurred, it returns a 0; otherwise, it returns -1 and sets the system variable errno
to one of the following values:
EBADF
- The file descriptor specified is invalid.
EINVAL
- No synchronization is possible because the system does not implement it.
Here is a code example that demonstrates the use of the write
, read
, and fsync
functions. (See Reading files at a low level, for more information on read
.)
#include <stdio.h> #include <fcntl.h> int main() { char my_write_str[] = "1234567890"; char my_read_str[100]; char my_filename[] = "snazzyjazz.txt"; int my_file_descriptor, close_err; /* Open the file. Clobber it if it exists. */ my_file_descriptor = open (my_filename, O_RDWR | O_CREAT | O_TRUNC); /* Write 10 bytes of data and make sure it's written */ write (my_file_descriptor, (void *) my_write_str, 10); fsync (my_file_descriptor); /* Seek the beginning of the file */ lseek (my_file_descriptor, 0, SEEK_SET); /* Read 10 bytes of data */ read (my_file_descriptor, (void *) my_read_str, 10); /* Terminate the data we've read with a null character */ my_read_str[10] = '