File exist

C

Claude Yih

Keith said:
ed said:
On 16 Apr 2006 01:53:03 -0700
Can anyone tell me how can I check that a file exist or no.
[...]
Try using stat(5).

There is no stat() function in standard C. Using it will limit the
portability of your code. See comp.unix.programmer.

I learnt from others that there is a function named access can be used
to detect if a dedicated file exists. The function is as follows:

int access (char* filename, int mode)

For instance, if I wanted to know whether /opt/test.log exists, I would
call this function as
int flag = access("/opt/test.log", 0);

However, this function is included in <io.h>, perhaps it's not a
standard function either.
 
F

Flash Gordon

Claude said:
Keith said:
ed said:
On 16 Apr 2006 01:53:03 -0700
(e-mail address removed) wrote:
Can anyone tell me how can I check that a file exist or no. [...]
Try using stat(5).
There is no stat() function in standard C. Using it will limit the
portability of your code. See comp.unix.programmer.

I learnt from others that there is a function named access can be used
to detect if a dedicated file exists. The function is as follows:

int access (char* filename, int mode)

For instance, if I wanted to know whether /opt/test.log exists, I would
call this function as
int flag = access("/opt/test.log", 0);

However, this function is included in <io.h>, perhaps it's not a
standard function either.

It is not part of standard C. As I'm sure others have said in this
thread standard C does not provide any portable method to see if a file
exists. So you can be sure that any method you find goes beyond what
standard C provides.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
M

Mr John FO Evans

Flash Gordon said:
Claude said:
Keith said:
On 16 Apr 2006 01:53:03 -0700
(e-mail address removed) wrote:
Can anyone tell me how can I check that a file exist or no.
[...]
Try using stat(5).
There is no stat() function in standard C. Using it will limit the
portability of your code. See comp.unix.programmer.

I learnt from others that there is a function named access can be used
to detect if a dedicated file exists. The function is as follows:

int access (char* filename, int mode)

For instance, if I wanted to know whether /opt/test.log exists, I would
call this function as
int flag = access("/opt/test.log", 0);

However, this function is included in <io.h>, perhaps it's not a
standard function either.

It is not part of standard C. As I'm sure others have said in this
thread standard C does not provide any portable method to see if a file
exists. So you can be sure that any method you find goes beyond what
standard C provides.

What is wrong with attempting to open the file and if there is no error
closing it again? Surely this is standard 'C'?

John
 
K

Kenneth Brody

Mr John FO Evans wrote:
[...]
[...]
What is wrong with attempting to open the file and if there is no error
closing it again? Surely this is standard 'C'?

Because if it fails, it won't (necessarily) tell you why. As has been
pointed out elsethread, insufficient access privileges will fail the
same way as a non-existent file. While many implementations will set
errno to the reason for the failure, such behavior is not guaranteed by
the Standard.

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

Flash Gordon

Mr said:
Flash Gordon said:
Claude said:
Keith Thompson wrote:

On 16 Apr 2006 01:53:03 -0700
(e-mail address removed) wrote:
Can anyone tell me how can I check that a file exist or no.
[...]
Try using stat(5).
There is no stat() function in standard C. Using it will limit the
portability of your code. See comp.unix.programmer.
I learnt from others that there is a function named access can be used
to detect if a dedicated file exists. The function is as follows:

int access (char* filename, int mode)

For instance, if I wanted to know whether /opt/test.log exists, I would
call this function as
int flag = access("/opt/test.log", 0);

However, this function is included in <io.h>, perhaps it's not a
standard function either.
It is not part of standard C. As I'm sure others have said in this
thread standard C does not provide any portable method to see if a file
exists. So you can be sure that any method you find goes beyond what
standard C provides.

What is wrong with attempting to open the file and if there is no error
closing it again? Surely this is standard 'C'?

It's standard C but it does not prove the file does not exist. It might
exist but your have permission set preventing you from opening it
(perhaps a different user owns it) or another process might have it
opened exclusively, or...
 
K

Keith Thompson

Mr John FO Evans said:
What is wrong with attempting to open the file and if there is no error
closing it again? Surely this is standard 'C'?

Yes, but it only tells you whether you were able to open the file; it
doesn't necessarily tell you why. (And fopen() doesn't even
necessarily set errno to a meaningful value.)

On some systems, it might be possible to open a file in binary mode
but not in text mode, or vice versa.

In some cases, it's not even possible to determine whether a file
exists; you might not have permission to ask (e.g., if the file is in
a directory you don't have permission to read). Also, a file might
exist when you test it, but cease to exist before you use it.

Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.
 
K

Kenneth Brody

Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}


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

Keith Thompson

Kenneth Brody said:
Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}

No, since the standard doesn't say that fopen() sets errno on failure.
perror() could print something silly like "foo.txt: No error", or
"foo.txt: File exists".
 
F

Flash Gordon

Kenneth said:
Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}

It's portable, but it might always print out "fopen() of %s failed.\n"
and never give a reason on some implementations.
 
M

Mr John FO Evans

After reading all the comments on this thread I am astounded that the 'C'
standard does not require that fopen returns a meaningful error when it
fails. Surly this is an ommision - or perhaps it is a acceptance that
computer systems suppliers do not like standards and hence do not provide
meaningful error returns from their lower level routines?

John
 
R

Richard Bos

Mr John FO Evans said:
After reading all the comments on this thread I am astounded that the 'C'
standard does not require that fopen returns a meaningful error when it
fails.

fopen() is required to return a null pointer when it fails. This means
"the file could not be opened". To require more information (e.g., in
errno) would be tricky. For example, how do you describe what level of
"meaningful" you demand without making assumptions about how the
underlying IO system works - assumptions that _will_ be inaccurate
sooner or later?
Surly this is an ommision - or perhaps it is a acceptance that
computer systems suppliers do not like standards and hence do not provide
meaningful error returns from their lower level routines?

It is at least an acknowledgement of the fact that _if_ you run across
such a crummy OS, you can't blame the implementation for not having more
information to give the user in the first place.

Richard
 
K

Keith Thompson

Mr John FO Evans said:
After reading all the comments on this thread I am astounded that the 'C'
standard does not require that fopen returns a meaningful error when it
fails. Surly this is an ommision - or perhaps it is a acceptance that
computer systems suppliers do not like standards and hence do not provide
meaningful error returns from their lower level routines?

Not at all. The C standard merely doesn't require *all*
implementations to report why fopen() failed. This allows C to be
implemented on a wide variety of systems, some of which may not always
provide meaningful information about errors.

The only errno values required by the C standard are EDOM, EILSEQ, and
ERANGE. (The corresponding error messages on one system are "Argument
out of domain", "Illegal byte sequence", and "Result too large",
respectively.)

But implementations are free to set errno on a failed fopen(), and to
provide more error codes than the minimal set required by the standard
-- and in fact most implementations do so.

Something like this:

errno = 0;
if ((f = fopen(filename, "r")) == NULL) {
perror(filename);
}

is very likely to give a meaningful error message on most systems --
and in fact is guaranteed to do so on many systems. If your
implementation doesn't give you a meaningful error message, you can
still complain to your vendor; you just can't argue that the
implementation doesn't conform to the C sftandard.

Having said that, I will acknowledge one weakness. There's no way for
a program to tell whether the implementation sets errno to a
meaningful value. You can generally tell by reading the
implementation's documentation, but that's not very helpful if you're
trying to write portable code.

If fopen() fails and errno is non-zero, it's possible that it was set
by some function called by fopen() for reasons having nothing to do
with fopen's failure. For example, fopen() might call malloc(),
malloc() could fail and set errno, then fopen() could fall back to
some alternative mechanism that doesn't use dynamically-allocated
memory, and then fail because the file doesn't exist. (That
particular scenario isn't very plausible, but something along those
lines could happen.)

It might have been more convenient if each library function defined in
the standard were required on failure to either (a) set errno to a
meaningful value, or (b) reset it to the value it had before the call.
If that were the case, then this:

errno = 0;
if ((f = fopen(filename, "r")) == NULL) {
if (errno == 0) {
fprintf(stderr, "fopen failed for %s\n", filename);
}
else {
perror(filename);
}
}

could always be depended on to produce a meaningful error message.
 
L

Laurent Deniau

Mr said:
After reading all the comments on this thread I am astounded that the 'C'
standard does not require that fopen returns a meaningful error when it
fails. Surly this is an ommision

I don't think so and I partially disagree with some answer in this
thread. Strictly speaking, a failure reported by fopen in "r+" mode
means that the file cannot be read nor write which is the same as "does
not exist" from the point of view of C, whatever the reason is. If you
want a more subtle diagnostic which matches better the user's
expectation, then you have to rely on the filesystem API (e.g. stat).
One cannot state that stat() is not standard on one hand and expect an
information about something that C ignores (e.g. access rights) on the
other hand.

my .02 euro.

a+, ld.
 
F

Flash Gordon

Laurent said:
I don't think so and I partially disagree with some answer in this
thread. Strictly speaking, a failure reported by fopen in "r+" mode
means that the file cannot be read nor write which is the same as "does
not exist" from the point of view of C, whatever the reason is.

I disagree, does not exist and cannot be opened are very different concepts.
> If you
want a more subtle diagnostic which matches better the user's
expectation, then you have to rely on the filesystem API (e.g. stat).
One cannot state that stat() is not standard on one hand and expect an
information about something that C ignores (e.g. access rights) on the
other hand.

Yes you can, it just means that you have to go to something outside the
C standard to achieve it, be that the Posix standard or some other
extension.
 
K

Kenneth Brody

Keith said:
Kenneth Brody said:
Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}

No, since the standard doesn't say that fopen() sets errno on failure.
perror() could print something silly like "foo.txt: No error", or
"foo.txt: File exists".

Hence the "errno=0" prior to fopen(), and the check for "errno != 0"
prior to calling perror().

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

Kenneth Brody

Flash said:
Kenneth said:
Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}

It's portable, but it might always print out "fopen() of %s failed.\n"
and never give a reason on some implementations.

Which I suppose qualifies for "can't be done portably" in terms of
actually getting the reason. However, the above is portable, and
will give the reason on those platforms that tell you why. On
platforms that don't tell you why, there's not much that you can
do, is there? (Even non-portably. Unless the "real" error number
is stored somewhere, but not placed in errno, sort of like the
Windows GetLastError() call. Of course, all the Windows C compilers
that I've seen set errno for you.)

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

Michael Wojcik

I disagree, does not exist and cannot be opened are very different concepts.

Always? I've seen filesystems where they're indistinguishable, such
as steganographic "deniable" filesystems where the proper key is
required to determine both the existence and contents of a particular
"file". Without that key, it's impossible to prove the existence or
nonexistence of the file.

Since it's completely possible to use such a filesystem under C's I/O
model (the "filename" passed to fopen becomes the key to the file),
there are potentially implementations for which there is no difference
between "does not exist" and "cannot be opened".

--
Michael Wojcik (e-mail address removed)

As always, great patience and a clean work area are required for fulfillment
of this diversion, and it should not be attempted if either are compromised.
-- Chris Ware
 
F

Flash Gordon

Michael said:
Always? I've seen filesystems where they're indistinguishable, such
as steganographic "deniable" filesystems where the proper key is
required to determine both the existence and contents of a particular
"file". Without that key, it's impossible to prove the existence or
nonexistence of the file.

My opinion is that your inability to see something does not change its
existence. So I would say that running under such a system just makes it
impossible to use non-standard means to determine if a file exists, that
does not translate in to the file not existing if you can't open it (or
tell it exists) because you don't have the key.
Since it's completely possible to use such a filesystem under C's I/O
model (the "filename" passed to fopen becomes the key to the file),
there are potentially implementations for which there is no difference
between "does not exist" and "cannot be opened".

With a system where it is guaranteed that no looking or permissions will
prevent you from opening a file then if you can't open a file it doesn't
exist. However, that *still* does not make the two concepts different,
it just makes detecting whether a file exists easy on *that* implementation.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
K

Keith Thompson

Kenneth Brody said:
Keith said:
Kenneth Brody said:
Keith Thompson wrote:
[...]
Usually the best approach is to try to open the file, and handle the
error if the attempt fails. Providing information about *why* it
failed can be useful, but it isn't absolutely necessary, and it can't
be done portably.

Isn't this portable?

... proper #include's, etc. implied ...

errno=0;
f = fopen(filename,mode);
if ( f == NULL )
{
if ( errno != 0 )
perror(filename);
else
fprintf(stderr,"fopen() of %s failed.\n",filename);
exit(EXIT_FAILURE);
}

No, since the standard doesn't say that fopen() sets errno on failure.
perror() could print something silly like "foo.txt: No error", or
"foo.txt: File exists".

Hence the "errno=0" prior to fopen(), and the check for "errno != 0"
prior to calling perror().

No, it's still not 100% portable (i.e., it's not guaranteed by the
standard). A failing fopen() could legally set errno to a non-zero
value that has nothing to do with the reason the fopen() call failed.
I presented a (rather implausible) example elsewhere in this thread.

I suspect that most real implementations set errno to something
meaningful, but it's not required.
 
K

Kenneth Brody

Keith said:
Kenneth Brody said:
Keith Thompson wrote: [...]
Hence the "errno=0" prior to fopen(), and the check for "errno != 0"
prior to calling perror().

No, it's still not 100% portable (i.e., it's not guaranteed by the
standard). A failing fopen() could legally set errno to a non-zero
value that has nothing to do with the reason the fopen() call failed.
I presented a (rather implausible) example elsewhere in this thread.

I know that the standard doesn't guarantee that fopen() will set errno
on failure. But does it really allow it to change errno to a non-zero
value that's not the actual error? Is this a "legal" implementation
within fopen()?

...
if ( it_failed )
{
errno = rand();
return(NULL);
}
...

Okay, so someone will probably point out that it's not allowed to call
rand() for some reason. :)

So how about:

if ( it_failed )
{
errno = (int)time(NULL);
return(NULL);
}
I suspect that most real implementations set errno to something
meaningful, but it's not required.

Well, does "99.99% portable" qualify? :)

I wonder if someone wants to implement a C environment where it does
all of the "legal, but probably not taken into account" behaviors?
Things like setting errno to something other than the "real" value,
or randomly zeroing memory on "a = i++".

No, this is not me volunteering to do so. :)

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

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
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top