"r+"
or "w+"
as the
mode
parameter in fopen
, then the file can be
read from and written to. This feature is useful when combined with
the use of fseek
and other related file position functions.
Essentially, the position of a file is an unsigned integer that
indicates the byte location (relative to the beginning of the file)
that the next read or write operation will use (but not when fopen
uses "a+"
as the mode
). fseek
goes to a
particular location in a file, ftell
returns the current
file position. rewind
goes back to position 0.
fgetpos
and fsetpos
are kind of like ftell
and fseek
, respectively. However, the f...pos
subroutines can utilize complex structures to represent the
file position, instead of just a long integer. This means
that using ftell
and fseek
, access to a file cannot
go beyond
bytes (about 2GB). However, with
f...pos
, the limitation is all based on the type
fpos_t
, which can be a structure that has no practical
range limitations.
Note that you can also access beyond the 32-bit integer range
limit by using fseeko
and ftello
. These functions
are similar to fseek
and ftell
, but the file position
parameter is of the type off_t
, which can become 64-bit
integers with the macro _FILE_OFFSET_BITS
defined as
64.
With file position functions, we can acquire and control the ``address'' of a structure in the file. This means we can implement ``pointers'' with structures that live in a file. The following is an example of a structure that lives in memory:
struct X { char name[30]; char gender; struct X *nextItem; };
If the same structure is to live in a file, then we need to change the structure definition as follows:
struct X { char name[30]; char gender; off_t nextItem; // this is now a file position! };
A structure still needs to be loaded into memory because we can
do anything with it. With the above structure definition, we can
print a list of structures using the following code (assuming
pFile
is already set up, and the file position is already
at the beginning of a structure):
struct X aRecord; do { if (!fread(&aRecord, sizeof(aRecord), 1, pFile)) { // error handling code } printf("%s [%c]\n", aRecord.name, aRecord.gender); if (aRecord.nextItem >= 0) { fseeko(pFile, aRecord.nextItem, SEEK_SET); } } while (aRecord.nextItem >= 0);
There are important difference between memory structures and file structures. Memory structures live in the process heap, which is shared amongst threads. As long as threads do not step on each other, it is okay to share a heap amongst threads. However, it is not a good idea to permit threads to operate on the same file, even if they do not step on the same structure.
Copyright © 2006-10-16 by Tak Auyeung