alternative to fstat ?

S

solarisss

I have thousands of files whose exitence needs to be checked.
I think fstat is too costly for this.
Is there any better way for the same ?
 
J

Joachim Schmitz

solarisss said:
I have thousands of files whose exitence needs to be checked.
I think fstat is too costly for this.
Is there any better way for the same ?
OT here, but in POSIX you'd have stat() (which would save you the fopen())
and access() (which should be much cheaper as it doesn't have to fill the
entire struct stat).

Bye, Jojo
 
R

Richard Tobin

Joachim Schmitz said:
OT here, but in POSIX you'd have stat() (which would save you the fopen())
and access() (which should be much cheaper as it doesn't have to fill the
entire struct stat).

I doubt access() would be significantly cheaper since it still has
to do a system call and get the inode of the file.

-- Richard
 
J

Joachim Schmitz

Richard Tobin said:
I doubt access() would be significantly cheaper since it still has
to do a system call and get the inode of the file.
It is significantly cheaper on a system I frequently work with.

Bye, Jojo
 
S

SM Ryan

# I have thousands of files whose exitence needs to be checked.
# I think fstat is too costly for this.
# Is there any better way for the same ?

stat information is not generally stored as part of the directory;
getting inode information generally generally requires a random
disc access. Some file systems might allow store inodes to improve
reading them, but that would be implementation dependent.
 
T

Thomas Maier-Komor

solarisss said:
I have thousands of files whose exitence needs to be checked.
I think fstat is too costly for this.
Is there any better way for the same ?

if the files are located in few common directories, fstatat might be an
option on Solaris. Don't know about other systems...

- Thomas
 
K

Kenneth Brody

Joachim said:
OT here, but in POSIX you'd have stat() (which would save you the fopen())
and access() (which should be much cheaper as it doesn't have to fill the
entire struct stat).

Well, if you have a file handle to pass to fstat(), I think we can
pretty much agree that the file exists. (Even if POSIX is OT here.)

:)

And, if I recall, a discussion in the past noted that a failed access()
call doesn't necessarily mean the file doesn't exist. (For example,
you may simply not have permission to check for the existence.) Also,
there was a discussion about some sort of "cryptographic filesystem"(?)
in which the existence of a file cannot be determined.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
J

Joachim Schmitz

Kenneth Brody said:
Well, if you have a file handle to pass to fstat(), I think we can
pretty much agree that the file exists. (Even if POSIX is OT here.)

:) Oops...

And, if I recall, a discussion in the past noted that a failed access()
call doesn't necessarily mean the file doesn't exist. (For example,
you may simply not have permission to check for the existence.) Also,
Very true, so you would have to check errno in case access() returns a -1.

printf("%s does%s exist\n", filename, ((access(filename) == -1) && (errno==
ENOFILE))? "n't":"");

The same is true for stat BTW(). And for fstat() resp. the open() it needs.

Bye, Jojo
 
K

Kenneth Brody

Joachim said:
Kenneth Brody said:
Joachim Schmitz wrote: [... use fstat() to check for file existence ...]
Well, if you have a file handle to pass to fstat(), I think we can
pretty much agree that the file exists. (Even if POSIX is OT here.)

:) Oops...

And, if I recall, a discussion in the past noted that a failed access()
call doesn't necessarily mean the file doesn't exist. (For example,
you may simply not have permission to check for the existence.) Also,
Very true, so you would have to check errno in case access() returns a -1.

printf("%s does%s exist\n", filename, ((access(filename) == -1) && (errno==
ENOFILE))? "n't":"");

The same is true for stat BTW(). And for fstat() resp. the open() it needs.

(I'm not sure why we're discussing POSIX here, but...)

What if the file doesn't exist in a directory to which you do not
have the proper permissions? I believe the error will be EPERM
(or, at least, not ENOFILE), and you will display "does exist".

The point is, an error other than ENOFILE does not imply that the
file does exist. I believe the same holds true for stat() et al.
The only thing you can reliably check for is whether you can open
the file, by seeing what fopen() returns. (Yes, you can use
something like access() to see if you have permission to a file
_at_the_time_you_call_access()_, but you have race conditions to
take into account.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

solarisss said:
I have thousands of files whose exitence needs to be checked.
I think fstat is too costly for this.
Is there any better way for the same ?

Since fstat() is defined by POSIX, I suggest that comp.unix.programmer
would provide better answers to your question.
 
J

Joachim Schmitz

Kenneth Brody said:
Joachim said:
Kenneth Brody said:
Joachim Schmitz wrote: [... use fstat() to check for file existence ...]
Well, if you have a file handle to pass to fstat(), I think we can
pretty much agree that the file exists. (Even if POSIX is OT here.)

:) Oops...

And, if I recall, a discussion in the past noted that a failed access()
call doesn't necessarily mean the file doesn't exist. (For example,
you may simply not have permission to check for the existence.) Also,
Very true, so you would have to check errno in case access() returns
a -1.

printf("%s does%s exist\n", filename, ((access(filename) == -1) &&
(errno==
ENOFILE))? "n't":"");
ENOENT, not ENOFILE
(I'm not sure why we're discussing POSIX here, but...)
Because ANSI/ISO C doesn't have fstat(), so the thread was OT from it's very
beginning
:cool:
What if the file doesn't exist in a directory to which you do not
have the proper permissions? I believe the error will be EPERM
(or, at least, not ENOFILE), and you will display "does exist".
The point is, an error other than ENOFILE does not imply that the
file does exist. I believe the same holds true for stat() et al.
OK, make it this then:
printf("%s %s exist\n", filename, ((access(filename) == -1) && (errno==
ENOENT))? "doesn't":"may");
The only thing you can reliably check for is whether you can open
the file, by seeing what fopen() returns. (Yes, you can use
something like access() to see if you have permission to a file
_at_the_time_you_call_access()_, but you have race conditions to
take into account.)
The OP was looking for an alternative to fstat() to check for the existence
of a file, that request seems entirly unneccessary, as fstat() requires the
file to have been open()ed first, hence proving that it exists and is
accessible.

To bring it back to topicallity, how about this:
#include <stdio.h>
#include <errno.h>

/*
* return 1 if file could be opened, proving it's existence, 0 otherwise,
* which is not a secure sign that the file doesn't exist!
*/
int faccess(char *filename)
{
FILE *fp;
/* mode got to be "r" or "r+", anything else would create it */
fp=fopen(filename, "r");
if (fp)
fclose(fp);

return fp?1:0;
}

/*
* returns 0 if filename does not exist, 1 if it exists and -1 if unsure
* i.e. if couldn't be opened for reading, but this could be due to
permissions
* to the file or some component of the file's path
*/
int fexist(char *filename)
{
errno=0;
(void)faccess(filename);
perror("");
switch (errno)
{
case 0: return 1;
case ENOENT: return 0;
default: return -1;
}
}



Bye, Jojo
 
C

Chris Torek

OT here, but in POSIX you'd have stat() (which would save you the fopen())
and access() (which should be much cheaper as it doesn't have to fill the
entire struct stat).

Using access() is usually the wrong approach, although this is not
the place to discuss why.

In this case, the best approach is probably to read the directory
(or directories) in which those "thousands of files" might be
stored, and then do your own in-memory lookups ... but this too is
off-topic, because ANSI C does not even support "read a directory"
type operations.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top