Even though stat() is not part of the current C standard, it is
available to C developers, in some form or another, on most of the
systems they might target.
Perhaps. It is certainly available in all POSIX-conformant systems.
Still, "available in most systems" is obviously not quite as good
as "available in all systems on which files are available".
Anyhow, using stat(), or a stat like function, should be a more
efficient than having to open each file and then attempting to read from
it to see if it contains any data.
Have you tested this? In particular, have you compared the
performance of the sequence:
stat the file to find out if it is empty.
then, open the file and if it was empty earlier, write an ID, but if it
was not empty, read the ID;
then, write any data;
finally, close the file.
vs:
open the file;
try to read the ID; if none available, write an ID;
then, write any data;
finally, close the file.
? Try it (with a large number of files) and see if you get the
results that *I* expect, namely, that the latter should be slightly
faster. (How much faster depends on the system. The reason is
that, on modern systems, "look up file by name" happens to be the
slowest file-related operation the system ever does. The "stat
then open" sequence looks up the file name twice. The "open then
manipulate" sequence looks up the file name just once. You can
achieve the same performance as the "test read" method by using
fstat() once the file is open, of course, if you are on a POSIX
system.)
Of course, the "best" way to open the file is often to use the
non-C-Standard function that says "open this file for reading and
writing, creating it if necessary, but not discarding existing
data". Standard C has only three ways to open for both reading
and writing:
method1 = fopen(filename1, "r+"); /* or r+b */
method2 = fopen(filename2, "w+"); /* or w+b */
method3 = fopen(filename2, "a+"); /* or a+b */
The file opened via method 1 must already exist -- if not, the
fopen() must fail and method1 will be NULL. Method 2 will create
the file, but an existing file opened via method 2 has any existing
data removed first, which is clearly not what is wanted in this
case. Method 3 will also create the file if it does not yet exist,
but has the drawback that *every* write to the file will append,
whether or not you positioned the file elsewhere with fseek().
If this is what you wanted, great, but if not -- well, there
really ought to be a variation on "r+" meaning "create file if
needed". Perhaps "r+c", or perhaps "R+" or "c+", for instance.
(If you have a POSIX system, you can use:
fd = open(filename, O_RDWR | O_CREAT, mode); /* but not O_TRUNC */
to get the actual file created if needed, followed by an fdopen()
call with either "r+" or "w+" to get the C-style "FILE *" stream.
Why an appropriate mode name was not put into C99 is something of
a mystery to me, though.)