Using fseek and ftell for Random File Access in C
In C file handling, fseek and ftell are
essential standard library functions that enable random access, allowing
developers to read or write data at any specific position within a file
rather than processing it sequentially from start to finish. This
article explains the core purpose of both functions, how their
parameters control the file position indicator, and how they work
together to navigate files, retrieve current offsets, and determine
total file sizes.
Understanding Random Access
By default, file operations in C (such as fread,
fwrite, fgetc, or fgets) operate
sequentially. Every read or write automatically advances the internal
file position indicator by the number of bytes processed. In many
applications—such as database engines, indexed file readers, or media
decoders—reading through gigabytes of data sequentially to reach a
specific record is inefficient. Random file access solves this problem
by directly jumping to the required byte offset.
The Purpose of fseek
The fseek function repositions the file position
indicator associated with a given file stream. Its function prototype is
defined in <stdio.h> as:
int fseek(FILE *stream, long offset, int whence);stream: A pointer to the openFILEobject.offset: A signed integer representing the number of bytes to shift the position indicator relative to the reference point defined bywhence. A positive value moves forward; a negative value moves backward.whence: The reference point from which the offset is applied. The C standard defines three constants for this argument:SEEK_SET: The beginning of the file.SEEK_CUR: The current position of the indicator.SEEK_END: The end of the file.
fseek returns 0 upon success and a non-zero
value if an error occurs, such as attempting an invalid seek operation
on a non-seekable stream (like a network socket or standard input).
The Purpose of ftell
The ftell function determines the current value of the
file position indicator. Its prototype is:
long ftell(FILE *stream);For binary streams, ftell returns the exact number of
bytes from the beginning of the file to the current position. For text
streams, the return value is an implementation-defined token that can
still be passed to fseek with SEEK_SET to
return to that exact position. If an error occurs, ftell
returns -1L and sets errno.
ftell is critical for bookmarking locations in a file
before navigating away, logging positions, or computing the sizes of
dynamically allocated buffers needed to store file contents.
Working Together: Common Use Cases
fseek and ftell are frequently used in
combination to perform operations that sequential file streams cannot
natively handle:
- Determining File Size: Moving the indicator to the
end of the file with
fseek(fp, 0, SEEK_END)and immediately callinglong size = ftell(fp)provides the complete byte size of the file. Afterward, callingfseek(fp, 0, SEEK_SET)(orrewind(fp)) resets the indicator so normal processing can begin. - Accessing Fixed-Width Records: If a binary file
contains uniform structs of size
N, the program can directly access recordiby computing the byte offset (i * sizeof(struct Record)) and callingfseek(fp, offset, SEEK_SET)before reading. - In-Place File Updates: When an entry needs
modification,
fseekallows the program to jump directly over existing bytes, overwrite the data withfwrite, and maintain the surrounding file structure without rewriting the entire file.