Previous Page
Next Page

13.2. Files

A file represents a sequence of bytes. The fopen( ) function associates a file with a stream and initializes an object of the type FILE, which contains all the information necessary to control the stream. Such information includes a pointer to the buffer used; a file position indicator , which specifies a position to access in the file; and flags to indicate error and end-of-file conditions.

Each of the functions that open filesnamely fopen( ), freopen( ), and tmpfile( )returns a pointer to a FILE object for the stream associated with the file being opened. Once you have opened a file, you can call functions to transfer data and to manipulate the stream. Such functions have a pointer to a FILE objectcommonly called a FILE pointeras one of their arguments. The FILE pointer specifies the stream on which the operation is carried out.

The I/O library also contains functions that operate on the file system, and take the name of a file as one of their parameters. These functions do not require the file to be opened first. They include the following:

  • The remove( ) function deletes a file (or an empty directory). The string argument is the file's name. If the file has more than one name, then remove( ) only deletes the specified name, not the file itself. The data may remain accessible in some other way, but not under the deleted filename.

  • The rename( ) function changes the name of a file (or directory). The function's two string arguments are the old and new names, in that order. The remove( ) and rename( ) functions both have the return type int, and return zero on success, or a non-zero value on failure. The following statement changes the name of the file songs.dat to mysongs.dat:

        if ( rename( "songs.dat", "mysongs.dat" ) != 0 )
          fprintf( stderr, "Error renaming \"songs.dat\".\n" );
    

Conditions that can cause the rename( ) function to fail include the following: no file exists with the old name; the program does not have the necessary access privileges; or the file is open. The rules for forming permissible filenames depend on the implementation.

13.2.1. File Position

Like the elements of a char array, each character in an ordinary file has a definite position in the file. The file position indicator in the object representing the stream determines the position of the next character to be read or written.

When you open a file for reading or writing, the file position indicator points to the beginning of the file, so that the next character accessed has the position 0. If you open the file in "append" mode, the file position indicator may point to the end of the file. Each read or write operation increases the indicator by the number of characters read from the file or written to the file. This behavior makes it simple to process the contents of a file sequentially. Random access within the file is achieved by using functions that change the file position indicator, fseek( ), fsetpos( ), and rewind( ), which are discussed in detail in "Random File Access," later in this chapter.

Of course, not all files support changing access positions. Sequential I/O devices such as terminals and printers do not, for example.

13.2.2. Buffers

In working with files, it is generally not efficient to read or write individual characters. For this reason, a stream has a buffer in which it collects characters, which are transferred as a block to or from the file. Sometimes you don't want buffering, however. For example, after an error has occurred, you might want to write data to a file as directly as possible.

Streams are buffered in one of three ways:


Fully buffered

The characters in the buffer are normally transferred only when the buffer is full.


Line-buffered

The characters in the buffer are normally transferred only when a newline character is written to the buffer, or when the buffer is full. A stream's buffer is also written to the file when the program requests input through an unbuffered stream, or when an input request on a line-buffered stream causes characters to be read from the host environment.


Unbuffered

Characters are transferred as promptly as possible.

You can also explicitly transfer the characters in the stream's output buffer to the associated file by calling the fflush( ) function. The buffer is also flushed when you close a stream, and normal program termination flushes the buffers of all the program's streams.

When you open an ordinary file by calling fopen( ), the new stream is fully buffered. Opening interactive devices is different, however: such device files are associated on opening with a line-buffered stream. After you have opened a file, and before you perform the first input or output operation on it, you can change the buffering mode using the setbuf( ) or setvbuf( ) function.

13.2.3. The Standard Streams

Three standard text streams are available to every C program on starting. These streams do not have to be explicitly opened. Table 13-1 lists them by the names of their respective FILE pointers.

Table 13-1. The standard streams

FILE pointer

Common name

Buffering mode

stdin

Standard input

Line-buffered

stdout

Standard output

Line-buffered

stderr

Standard error output

Unbuffered


stdin is usually associated with the keyboard, and stdout and stderr with the console display. These associations can be modified by redirection. Redirection is performed either by the program calling the freopen( ) function, or by the environment in which the program is executed.


Previous Page
Next Page