Checkup: better way to test for file existence?

M

Matt

Hello,

I see other references in this newsgroup saying that the only standard
C++ way to test for file existence is some variant of my code below;
can someone please confirm...or offer alternatives?

Additionally, might there be cross-platform alternatives, say in a
library like Boost, or something else?

-Matt

#include <fstream>

/*
[class FileHandle contains 'fstream file' and previously-initialed
'string filename'.]
*/

bool
FileHandle::exists()
{
bool retval = false;

// TODO/XXX: Is there a better way to
// test the existence of a file
// without opening it?

file.open(filename.c_str(), ios::in | ios::binary);

if (!file.fail()) retval = true;

file.close();

return retval;
}
 
M

Mike Wahler

Matt said:
Hello,

I see other references in this newsgroup saying that the only standard
C++ way to test for file existence is some variant of my code below;
can someone please confirm...or offer alternatives?

You must have misread them, or read some that were not
correct. There is no way in standard C++ to detect
conclusively the nonexistence of a file. (If an
open succeeds when using a mode other than once which
will create a nonexistent file, then of course that
does indicate that the file previously existed). But
if an open fails, that does not necessarily mean it
doesn't exist. All you can determine is if an attempt
to open a file succeeded or failed. An attempt to open
could fail for a variety of reasons depending upon the
environment, including but not limited to: insufficient
OS permissions, device where file resides is offline, does
not exist, etc. Many implementations do provide extensions
for obtaining more detailed information about i/o, but
they're not standard.
Additionally, might there be cross-platform alternatives, say in a
library like Boost, or something else?

There probably are some which address at least a small
number of environments. Try google.

-Matt

#include <fstream>

/*
[class FileHandle contains 'fstream file' and previously-initialed
'string filename'.]
*/

bool
FileHandle::exists()
{
bool retval = false;

// TODO/XXX: Is there a better way to
// test the existence of a file
// without opening it?

Depends upon what 'better' means. There is no way
at all using standard C++. AFAIK platform-specific
solutions are provided by most implementations.
file.open(filename.c_str(), ios::in | ios::binary);

if (!file.fail()) retval = true;

file.close();

return retval;
}

If this function returns 'false', all that means
is that the file could not be opened (for an unknown
reason). Nothing more, nothing less.

-Mike
 
W

wittempj

You can test this with an old school C function:

#include "unistd.h."
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
int ret(0);
std::string fname("C:\\AUTOEXEC.BAT");
ret = access(fname.c_str(), F_OK);
if (ret == -1)
std::cout << "Access on file " << fname << " is denied" <<
std::endl;

system("Pause");
return EXIT_SUCCESS;
}

more specific tests this if you can get access to the file.
 
R

Rolf Magnus

Matt said:
bool
FileHandle::exists()
{
bool retval = false;

// TODO/XXX: Is there a better way to
// test the existence of a file
// without opening it?

Why would you want to test for the existence of a file if you don't want to
open it?
If you just want to make sure it's there so you can open it later, that's
not a good idea since something could change in between (file
removed/created/renamed, permissions changed, device unmounted, whatever).
 
M

Mike Wahler

(e-mail address removed)> wrote in message
You can test this with an old school C function:

'access()' is not a C (or C++) function, it's an extension
provided by some implementations. Also your use of it below
does not indicate a guarantee of a file's existence or nonexistence,
only whether it is accessible. An fstream object can already provide
this information.
#include "unistd.h."
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
int ret(0);
std::string fname("C:\\AUTOEXEC.BAT");
ret = access(fname.c_str(), F_OK);
if (ret == -1)
std::cout << "Access on file " << fname << " is denied" <<
std::endl;

system("Pause");
return EXIT_SUCCESS;
}

more specific tests this if you can get access to the file.

Here the topic is ISO standard C++. Your 'solution' is specific
to a UNIX implementation, so is not applicable to other platforms,
and is not topical here.

-Mike
 
M

Matt

Why would you want to test for the existence of a file if you don't want to
open it?

I'm using (in an application I'm building to simulate a
more-complicated, future design) the existence or non-existence of
files as a means of inter-process communication.

(eg, while one process is processing a certain event, it writes a
zero-sized-file, then deletes said file when the event completes. A
separate process polls the existence of said file to see if the event
is continuing. I doubt I can give you many more details beyond that
without explaining more in depth my application and prototype.)
If you just want to make sure it's there so you can open it later, that's
not a good idea since something could change in between (file
removed/created/renamed, permissions changed, device unmounted, whatever).

Yes, obviously. However, that's not what I'm trying to do. See
above.

-Matt
 
M

Matt

You must have misread them, or read some that were not
correct. There is no way in standard C++ to detect
conclusively the nonexistence of a file.

Fair enough. I'll rephrase my question:

What might you recommend as the best possible method/algorithm to
detect the non-existence of a file (even though it may not catch all
cases as noted below) in lieu of having a definitive means to do so
accurately.

As I read from the info below, there is no conclusive way to do this.
Hence there is no real answer to the problem.

What I'm looking for are alternative answers that get me "as close as
possible."
There probably are some which address at least a small
number of environments. Try google.

Thanks for the google tip. I have been looking, even prior to this
post. My search was not initially productive, hence my post here.

-Matt
 
M

Mike Wahler

Matt said:
Fair enough. I'll rephrase my question:

What might you recommend as the best possible method/algorithm to
detect the non-existence of a file (even though it may not catch all
cases as noted below) in lieu of having a definitive means to do so
accurately.

As I read from the info below, there is no conclusive way to do this.
Hence there is no real answer to the problem.

What I'm looking for are alternative answers that get me "as close as
possible."

If you open the file as "input only, don't create" then
barring the circumstances I cited, a return of 'true'
from 'istream::fail()' would probably mean 'not found'.

std::ifstream input("filename");
if(!input)
std::cerr << "open failed, file probably does not exist\n";

-Mike
 
S

sqaengineering

You could try something like this:

bool FileExists( std::string strFile )
{
bool bSuccess = true;
struct _stat stFile;

if( _stat( strFile.c_str(), &stFile ) == -1 )
bSuccess = false;

return bSuccess;
}

For linux, replace _stat with stat...
 
M

Matt

if( _stat( strFile.c_str(), &stFile ) == -1 )

Excellent recommendation, I should have thought of this POSIX-based
stat() function earlier.

(It's been a long time since I've done system programming...it's
starting to come back to me now...and I've dug up my beloved, purple
"POSIX Programmer's Guide" book. Yes, I know this is not "standard"
C++, but it seems to be the next best thing, and with cygwin/mingw on
my Windows machines, I seem to be POSIX compliant on virtually every
platform I choose...I hope?)

-Matt
 
M

Matt

Hi Mike, Thanks for this clarification. -Matt

If you open the file as "input only, don't create" then
barring the circumstances I cited, a return of 'true'
from 'istream::fail()' would probably mean 'not found'.

std::ifstream input("filename");
if(!input)
std::cerr << "open failed, file probably does not exist\n";

-Mike
 
W

wittempj

Point taken. It compile and executes on windows as well for code
compiled with g++ though - so it is not strictly a unix call ....
 
R

Richard Herring

Rolf Magnus said:
Why would you want to test for the existence of a file if you don't want to
open it?

A program for producing lists of files springs to mind ;-)
 
R

Rolf Magnus

Richard said:
A program for producing lists of files springs to mind ;-)

lol, you mean sort of a brute-force way to get a directory listing without
actual directory support? I guess that'd take quite some time, even if you
assume "good" old DOS with it's case insensitive 8.3 file names. :)
 

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,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top