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] = '