104

I have read the answers for What's the best way to check if a file exists in C? (cross platform), 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.

Both stat and access are pretty much ungoogleable. What should I #include to use these?

2
  • <io.h> for access (which might actually be _access). Commented Nov 6, 2008 at 10:10
  • Yes, as therefromhere pointed out. Commented Nov 6, 2008 at 12:50

10 Answers 10

182

Use boost::filesystem:

#include <boost/filesystem.hpp> if ( !boost::filesystem::exists( "myfile.txt" ) ) { std::cout << "Can't find my file!" << std::endl; } 
Sign up to request clarification or add additional context in comments.

16 Comments

Seems to be a bit of a hazzle to install a huge third party library to do something that should be simple
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!
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...
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: open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Surprised no one has mentioned this, but this will return 'true' for directories too. myfile.txt could be a directory on linux or windows. If you want to require it be a file, you can use boost::filesystem::is_regular_file().
|
43

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

1 Comment

The link is not available any more.
30

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.

2 Comments

But with this code you would also jump into the if clause if you don't have permissions for the file, although it exists. In most cases it won't matter, but still worth mentioning.
Noticed that good() also yields true if the given argument denotes a directory, see stackoverflow.com/questions/9591036/…
18

If your compiler supports C++17 you don't need boost, you can simply use std::filesystem::exists

#include <iostream> // only for std::cout #include <filesystem> if (!std::filesystem::exists("myfile.txt")) { std::cout << "File not found!" << std::endl; } 

Comments

13

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.

2 Comments

Nice answer +1 for NOT USING BOOST, since it's an overkill, however it wasn't trivial to write that from what is provided here, so I just posted an answer. Check it please.
9

How about access?

#include <io.h> if (_access(filename, 0) == -1) { // File does not exist } 

2 Comments

Is io.h normaly available on windows and linux even if its not standard?
access() is POSIX function that is available via <unistd.h> on Linux.
9

Another possibility consists in using the good() function in the stream:

#include <fstream> bool checkExistence(const char* filename) { ifstream Infield(filename); return Infield.good(); } 

Comments

7

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?

1 Comment

What if you're writing a ls-like program ? I'm guessing the original poster here doesn't want to open the file, at all. Posix's stat function is supposed to give you informations about the file's permissions though, so it would fix that problem.
3

NO REQUIRED, which would be an overkill.


Use stat() (not cross platform though as mentioned by pavon), like this:

#include <sys/stat.h> #include <iostream> // true if file exists bool fileExists(const std::string& file) { struct stat buf; return (stat(file.c_str(), &buf) == 0); } int main() { if(!fileExists("test.txt")) { std::cerr << "test.txt doesn't exist, exiting...\n"; return -1; } return 0; } 

Output:

C02QT2UBFVH6-lm:~ gsamaras$ ls test.txt ls: test.txt: No such file or directory C02QT2UBFVH6-lm:~ gsamaras$ g++ -Wall main.cpp C02QT2UBFVH6-lm:~ gsamaras$ ./a.out test.txt doesn't exist, exiting... 

Another version (and that) can be found here.

2 Comments

Not the downvoter, but the question asked for a cross-platform solution, and stat doesn't exist on all platforms.
This is a good workaround for Android NDK not yet implementing std::filesystem::exists
1

If you are already using the input file stream class (ifstream), you could use its function fail().

Example:

ifstream myFile; myFile.open("file.txt"); // Check for errors if (myFile.fail()) { cerr << "Error: File could not be found"; exit(1); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.