From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe)
Newsgroups: comp.lang.c
Subject: Re: File Handling
Date: 14 Sep 92 07:44:00 GMT
Organization: Comp Sci, RMIT, Melbourne, Australia

In article <290wqB3w165w@cybrspc.UUCP>, roy%cybrspc@cs.umn.edu (Roy M. Silvernail) writes:
> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
> > You also want to find out about the ANSI functions fgetpos(), fsetpos().
> 
> I know this may be a stoopid question, but I just looked up those two
> calls in my manual.  Whatever good are they?

They replace the obsolescent functions ftell() and fseek().
The problem with ftell() and fseek() is that they have to represent
file positions in a 'long'.  ANSI C guarantees that 'long' is at least
32 bits, but for some file systems that isn't anywhere near big enough.
For example, in VMS a "Record File Address" can be 6 bytes.  (It's
actually a 32-bit block number and a 9-bit byte offset within block,
so the effective addressing range is more like 40 bits.)  A record may
have up to 32,767 bytes, so to represent a position in such a way that
VMS can find the right byte takes 6+2=8 bytes.  Or take VM/CMS, which
has random-access files, but they are accessed by _record_ number (even,
and this is a neat trick, when the records are variable in length).
To represent the location of a byte in such a file, you would need to
keep track of the record number and the byte offset within the record.
(Note that you _can't_ calculate the record number from an "absolute"
byte address, because in the presence of variable-length records there
is no simple arithmetic mapping from byte number to record number.)
And if the file is a text file, you might want to keep track of whether
the position was within a block of 16-bit (DBCS) characters or within
a block of 8-bit (SBCS) characters.

So fgetpos() and fsetpos() let you do absolutely everything that it was
ever possible to do __portably__ with ftell() and fseek(), namely
remember a place that you've been and go back there later, but they are
more portable (can work with larger files).

> The vast
> majority of file positioning I do is related to locating data within the
> file, for which I must calculate a position.

I had such a hard time hammering into the heads of the BSI & ISO Prolog
committees that seeking-to-an-arbitrary-byte-position is not a portable
operation.  Trust me, it isn't.  If you want to do this, your code will
work on the operating systems that you have explicitly designed your
code for (absent bugs, of course).  It isn't even particularly hard to
make byte-seeking code that works under DOS, OS/2, and UNIX all three.
Portable to other environments in general it will not be.

> It doesn't appear that
> fsetpos() is useful for that purpose.  So, why use it at all?

It is useful for building indexes.  You can traverse some file, extracting
keys and positions, and store the keys and positions in a data structure
that you can use for looking up records by content.  This can be done
portably, so you can get direct access to records, you just have to
remember the positions instead of calculating them.

Note that there is nothing in the C standard to _stop_ you using
functions like open(), lseek(), read(), write(), and close() if you
really want to and if your C system provides them.
All the C standard does is say "C does not have a _portable_ way of
doing that."
-- 
You can lie with statistics ... but not to a statistician.