File
Positioning
int fgetpos(FILE * restrict stream,fpost *
restrict pos);
int fseek(FILE *stream, long int
offset, int whence);
int fsetpos(FILE *stream, const
fpos_t *pos);
long int ftell (FILE *stream) void rewind(FILE
*stream);
Every stream has an associated file position.
When a tile is opened, the file position is set at the beginning of the file.
(If the tile is opened in "append" mode, however, the initial tile
position may be at the beginning or end of the tile, depending on the
implementation.) Then, when a read or write operation is performed, the file
position advances automatically, allowing us to move through the file in a
sequential manner.
Although
sequential access is fine for many applications, some programs need the ability
to jump around within a file, accessing some data here and other data there. If
a file contains a series of records, for example, we might want to jump
directly to a particular record and read it or update it.
supports this form of access by providing five functions that allow a program
to determine the current lile position or to change it.
The f seek
function changes the file position associated with the first argument (a file
pointer). The third argument specifies whether the new position is to be
calculated wilh respect to the beginning of the file, the current position, or
the end of the file. defines three macros for this purpose:
SEEK_SET Beginning of file
SEEK_CUR Current file position
SEEK END End of file
The
second argument is a (possibly negative) byte count. To move to the beginning
of a tile, for example, the seek direction would be SEEK_SET and the byte count would be
zero:
fseek(fp, OL, SEEK_SET); /* moves to beginning of file */
To move to the end of a file, the seek direction
would be SEEK_END:
fseek(fp, OL, SEEK_END); /* moves to end of file */
To move
back 10 bytes, the seek direction would be SEEK CUR and the byte count would be
-10:
fseek(fp,
-10L, SEEK_CUR); /* moves back 10 bytes */
Note that the byte count has type long int, so I've used
OL and -10L as arguments. (0 and -10 would also work,
of course, since arguments are converted to the proper type automatically.)
Normally,
fseek returns zero. If an error occurs (the requested position doesn't exist,
for example), fseek returns a nonzero value.
The
file-positioning functions are best used with binary streams, by the way. C
doesn't prohibit programs from using them with text streams, but care is
required because of operating system differences, fseek in particular is
sensitive to whether a stream is text or binary. For text streams, either (1)
offset (f seek's second argument) must be zero or (2) whence (its third
argument) must be SEEK_SET and offset a value obtained by a previous
call of f tell. (In other words, we can only use fseek to move to the beginning
or end of a text stream or to return to a place that was visited previously.)
For binary streams, fseek isn't required to support calls in which whence is
SEEK_END.
The f tell
function returns the current file position as a long integer. (If an error
occurs, f tell returns -1L and stores an error code in errno.) The value
returned by f tell may be saved and later supplied to a call of fseek, making
it possible to return to a previous file position:
long
file_pos;
file_pos = ftell(fp); /* saves current position */
fseek(fp,
file_pos, SEEK_SET); /* returns to old position */
If
fp is a binary stream, the call ftell (fp)
returns the current file position as a byte count, where zero represents the
beginning of the file. If fp is a text stream, however, ftell (fp) isn't necessarily a byte count. As a result, it's best
not to perform arithmetic on values returned by ftell.
Rewind Function
The
rewind function sets the file position at the beginning. The call rewind (fp)
is nearly equivalent to fseek (fp, OL, SEEK_SET). The difference? rewind
doesn't return a value but does clear the error indicator for f p.
fseek and
ftell have one problem: they're limited to files whose positions can be stored
in a long integer. For working with very large files, C provides two
additional functions: fgetpos and fsetpos. These functions can handle large
tiles because they use values of type f pos_t to represent tile positions. An
fpos_t value isn't necessarily an integer: it could be a structure, for
instance.
The call
fgetpos (fp, &cfile_pos) stores the file position associated with fp in the
f ile_pos variable. The call fsetpos (fp, &f ile_pos) sets the file
position for fp to be the value stored in f ile pos. (This value must have been
obtained by a previous call of fgetpos.) If a call of fgetpos or fsetpos fails,
it stores an error code in errno. Both functions return zero when they succeed
and a nonzero value when they fail.
Here's how we might
use fgetpos and fsetpos to save a file position and return to it later:
fpos_t file_pos;
fgetpos(fp, &file_pos); /* saves
current position */
fsetpos(fp, &file_pos); /*
returns to old position */
No comments:
Post a Comment