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;
}