tags:

views:

2469

answers:

7

I have read the answers for this question but I'm wondering if there is a better way to do this using standard c++ libs? Preferably without trying to open the file at all.

Edit: Thanks for the answers so far, but I'm still stuck... Both "stat" and "access" is pretty much ungoogleable. What should I #include to use these?

+4  A: 

Use stat(), if it is cross-platform enough for your needs. It is not C++ standard though, but POSIX.

On MS Windows there is _stat, _stat64, _stati64, _wstat, _wstat64, _wstati64.

divideandconquer.se
Ok, what do I #include?
c0m4
<sys/types.h> and <sys/stat.h>See http://msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx
divideandconquer.se
+14  A: 

Use boost::filesystem:

if ( !boost::filesystem::exists( "myfile.txt" ) )
{
  std::cout << "Can't find my file!" << std::endl;
}
Andreas Magnusson
Seems to be a bit of a hazzle to install a huge third party library to do something that *should* be simple
c0m4
Boost is a library where much of what will eventually be a part of C++ standard library is developed. Many of the people involved with boost are people involved with the C++ standard. So boost isn't just *any* third party library. If you're programming in C++ you *should* have boost installed!
Andreas Magnusson
@Andreas Magnusson; I would vote you up for this comment!! FULL ACK!
Peter Parker
Thanks, I love boost too!
Andreas Magnusson
I seem to recall that b::fs::exists returns "true" on non-existent files on network shares: "\\machine\share\this_file_doesnt_exist" => true. Last time I checked was on boost 1.33, use caution...
rlerallut
I tested it with Boost 1.36 and it works as it should.
Andreas Magnusson
If your compiler comes with a tr1 implementation, you don't even need to install Boost. It will be in the std::tr1::filesystem
Nemanja Trifunovic
Actually ASFAIK it didn't make TR1 but will be added at a later stage. I also didn't find any references to it in the official TR1 draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Andreas Magnusson
+1  A: 

How about access?

#include <io.h>

if (_access(filename, 0) == -1)
{
    // File does not exist
}
Rob
Is io.h normaly available on windows and linux even if its not standard?
c0m4
access() is POSIX function that is available via <unistd.h> on Linux.
Alex B
+1  A: 

To help with your problems googling, try adding "man page" to the search - if you're on Linux, the "man" command is your friend.

therefromhere
Great tip thanks!
c0m4
Haven't you noticed? This site is for people who don't have Google.
fizzer
This site is for people fed up with Google bringing back wrong or stupid answers.
Neil
+3  A: 

I would reconsider trying to find out if a file exists. Instead, you should try to open it (in Standard C or C++) in the same mode you intend to use it. What use is knowing that the file exists if, say, it isn't writable when you need to use it?

fizzer
+3  A: 

I am a happy boost user and would certainly use Andreas' solution. But if you didn't have access to the boost libs you can use the stream library:

ifstream file(argv[1]);
if (!file)
{
    // Can't open file
}

It's not quite as nice as boost::filesystem::exists since the file will actually be opened...but then that's usually the next thing you want to do anyway.

MattyT
+2  A: 

Be careful of race conditions: if the file disappears between the "exists" check and the time you open it, your program will fail unexpectedly.

It's better to go and open the file, check for failure and if all is good then do something with the file. It's even more important with security-critical code.

Details about security and race conditions: http://www.ibm.com/developerworks/library/l-sprace.html

rlerallut