[vox-tech] [C] randomly accessing file data in C

Jeff Newmiller vox-tech@lists.lugod.org
Wed, 21 May 2003 13:11:45 -0700 (PDT)


On Wed, 21 May 2003, Micah J. Cowan wrote:

> On Wed, May 21, 2003 at 09:50:38AM -0700, Ken Herron wrote:
> > 
> > 
> > --On Wednesday, May 21, 2003 09:05:15 -0700 "Micah J. Cowan" 
> > <micah@cowan.name> wrote:
> > 
> > > On Tue, May 20, 2003 at 06:45:53PM -0700, Mark K. Kim wrote:
> > >> Hello...
> > >>
> > >> I'm trying to access data in a file in C.  I want to read some portion
> > >> of it, modify it, then rewrite that portion back into the file.
> > >
> > > I don't think what you're trying to do is possible. What you *can* do,
> > > is read in the file in chunks of an appropriate size for keeping in
> > > memory, and writing them out to a new (temporary) file as you go. As
> > > soon as you reach the spot you need to modify, you just modify the
> > > data you are going to write out to the new file, and then copy the
> > > tail end of the original, chunk-by-chunk, into the temporary file.
> > 
> > Er, what?  Overwriting part of a file is a normal operation. Kim's 
> > problem is that he's opening the output file in "w+" mode, which 
> > truncates the file.
> 
> Um, sorry. I was thinking from a comp.lang.c perspective. I never use
> that technique if I expect it to work on other systems, because as far
> as the ISO C standard is concerned, writing to any point in the middle of a
> file may result in truncation, regardless of which mode was used.

If this were true, it would be a major limitation of Standard C... so I
looked further and found that it is not.

ANSI Standard C (1989), which essentially became ISO C, Section 4.9.5.3
(page 131) line 5, says:

  When a file is opened with update mode ('+' as the second or third
  character in the above list of mode argument values), both input and
  output may be performed on the associated stream.  However, output may
  not be directly followed by input without an intervening call to the
  fflush function or to a file positioning function (fseek, fsetpos, or
  rewind), and input may not be directly followed by output without an
  intervening call to a file positioning function, unless the input
  operation encounters end-of-file.  Opening (or creating) a text file
  with update mode may instead open (or create) a binary stream in some
  implementations.

Further, Section 4.9.3 (page 127) line 12 says:

  Binary files are not truncated, except as defined in 4.9.5.3.  Whether a
  write on a text stream causes the associated file to be truncated beyond
  that point is implementation-defined.

Truncation is mentioned only with regard to specific file open modes.
"r+b" has no mention of truncation.

In short, I think binary updates without truncation _are_ supported in
C89.  (whew!)  I don't have a copy of C99... perhaps you can check there.

This position is supported by the comp.lang.c FAQ:
http://www.eskimo.com/~scs/C-faq/q12.30.html

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil@dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------