Node:File position, Next:, Previous:Block input and output, Up:High-level file routines



File position

When a person reads a book, her "location" in the book can be specified by a page number (and even a line number or word number, at finer levels of detail). Just so, it is possible (and often useful!) to know the location, or file position, of a stream reading from or writing to a file. And just as we sometimes want to know which chapter a friend is currently reading in a book, or to recommend that he flip backward or forward to an interesting passage, so it is frequently useful to be able to change the current file position to access a more interesting part of the file.

At the high level of the functions in this section, GNU treats all streams as streams of characters -- even binary streams like the one associated with the file numbers.dat in the example for fread and fwrite. (See Block input and output.) This means that the file position of any stream is a simple character count -- file position 0 means that we are reading or writing the first character in the file, file position 522 means that we are reading the 523rd character, and so on. (Just as with arrays in C, file positions are zero-based.)

Not only does the file position of a stream describe where in the file the stream is reading or writing, but reading or writing on the stream advances the file position. During high-level access to a file, you can change the file position at will. Any file that permits changing the file position in an arbitrary way is called a random-access file. (Many years ago, the people who invented computer jargon chose the word "random" to be part of the phrase "random-access" because, from the point of view of the computer, a random-access file can be read from or written to at any location, as if at random. Of course, programmers are not working randomly; they decide where their programs should read and write. The term RAM for random-access memory comes from the same source.)

The main high-level function to tell where the current file position is, is called appropriately, ftell. It accepts a single parameter -- a file stream -- and returns a long integer representing the file position.1 (See libc, for more information.)

The main function to seek a different file position is called fseek. It accepts three parameters. The first parameter is the stream in question, the second is a long integer offset, and the third parameter is a constant that specifies whether the offset is relative to the beginning of the file (SEEK_SET), to the current file position (SEEK_CUR), or to the end of the file (SEEK_END). The fseek function returns 0 if the operation was successful, or a nonzero integer value otherwise. (A successful fseek operation also clears the end-of-file indicator (see below), and discards the results of ungetc. See ungetc.)

There is a simple macro called rewind that will take the file pointer back to the beginning of the file. You must simply pass it the stream that you want to rewind; it does not return a value. It is the same as calling fseek on the stream with an offset of 0 and a third parameter of SEEK_SET, except that it resets the error indicator for the stream and, as mentioned, there is no return value.

An example of these functions will not be useful until we have introduced single-character I/O. See getc and fgetc, if you want to read a code example that uses the ftell, fseek, and rewind functions.


Footnotes

  1. Since the file position is a long integer, the length of a file using one of these functions cannot be any greater than the maximum value of a 32-bit long integer under GNU, plus one (since the file position is zero-based) --- that is, such a file cannot be any more than 2,147,483,648 bytes, or about two gigabytes long. If you need to use longer files, you can use low-level file routines, which allow for longer files and file positions through such 64-bit functions as lseek64.