What’s the best way to check if a file exists in C++? (cross platform)
Solution 1
Use boost::filesystem:
#include <boost/filesystem.hpp>
if ( !boost::filesystem::exists( "myfile.txt" ) )
{
std::cout << "Can't find my file!" << std::endl;
}
Solution 2
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
Solution 3
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.
Solution 4
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;
}
Solution 5
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.
Related videos on Youtube
c0m4
B.Sc from Mariestad, Sweden. Works with embedded software. I live in an 100 year old house with my wife and two daughters. I like C and python.
Updated on March 05, 2020Comments
-
c0m4 about 4 years
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
andaccess
are pretty much ungoogleable. What should I#include
to use these?-
Rob over 15 years<io.h> for access (which might actually be _access).
-
c0m4 over 15 yearsYes, as therefromhere pointed out.
-
-
c0m4 over 15 yearsSeems to be a bit of a hazzle to install a huge third party library to do something that should be simple
-
Andreas Magnusson over 15 yearsBoost 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!
-
c0m4 over 15 yearsIs io.h normaly available on windows and linux even if its not standard?
-
rlerallut over 15 yearsI 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...
-
Alex B over 15 yearsaccess() is POSIX function that is available via <unistd.h> on Linux.
-
Nemanja Trifunovic over 15 yearsIf your compiler comes with a tr1 implementation, you don't even need to install Boost. It will be in the std::tr1::filesystem
-
Andreas Magnusson over 15 yearsActually 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
-
activout.se over 15 years<sys/types.h> and <sys/stat.h> See msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx
-
scigor over 13 yearsBut 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.
-
Ela782 almost 11 yearsI think they said at BUILD2013 that a standard-committee working group is working on that and they will include it (most likely boost::fs v2) as a package separate from C++14 but at similar time.
-
Pritesh Acharya over 10 yearsboost::filesystem::exists checks the existance of absolute path. how to check the existence of relative path.?
-
Andreas Magnusson over 10 years@PriteshAcharya:
boost::filesystem::exists(boost::filesystem::absolute(relativePath))
-
FelixJongleur42 over 10 yearsNoticed that good() also yields true if the given argument denotes a directory, see stackoverflow.com/questions/9591036/…
-
Marcel Tricolici almost 10 yearsunfortunately boost filesystem cannot be used in windows phone :((
-
HelloWorld over 8 yearsI agree, even a lot of parts are moved to - or influenced C++ - IMHO boost is not the solution for everything. I appreciate non-templates when possible. Keep your source safe and simple.
-
Andreas Magnusson over 8 years@HelloWorld: I fail to see any templates in the code above. Is the snippet above not the simplest possible?
-
Rastikan over 8 yearsGood tip, but ended up not using it because boost::filesystem::exists ( path.cpp) requires yet another module or library std::locale::locale(char const*)
-
Michael about 8 yearsWhat 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. -
gsamaras almost 8 yearsNice 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.
-
pavon about 7 yearsNot the downvoter, but the question asked for a cross-platform solution, and stat doesn't exist on all platforms.
-
void.pointer over 4 yearsSurprised 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 useboost::filesystem::is_regular_file()
. -
John over 2 yearsThe link is not available any more.