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] = '\0'; printf ("String read = %s.\n", my_read_str); close (my_file_descriptor); return 0; }