What’s the best way to check if a file exists in C++? (cross platform)

116,664

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.

Share:
116,664

Related videos on Youtube

c0m4
Author by

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, 2020

Comments

  • c0m4
    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 and access are pretty much ungoogleable. What should I #include to use these?

    • Rob
      Rob over 15 years
      <io.h> for access (which might actually be _access).
    • c0m4
      c0m4 over 15 years
      Yes, as therefromhere pointed out.
  • c0m4
    c0m4 over 15 years
    Seems to be a bit of a hazzle to install a huge third party library to do something that should be simple
  • Andreas Magnusson
    Andreas Magnusson over 15 years
    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!
  • c0m4
    c0m4 over 15 years
    Is io.h normaly available on windows and linux even if its not standard?
  • rlerallut
    rlerallut over 15 years
    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...
  • Alex B
    Alex B over 15 years
    access() is POSIX function that is available via <unistd.h> on Linux.
  • Nemanja Trifunovic
    Nemanja Trifunovic over 15 years
    If 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
    Andreas Magnusson over 15 years
    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
  • activout.se
    activout.se over 15 years
    <sys/types.h> and <sys/stat.h> See msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx
  • scigor
    scigor over 13 years
    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.
  • Ela782
    Ela782 almost 11 years
    I 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
    Pritesh Acharya over 10 years
    boost::filesystem::exists checks the existance of absolute path. how to check the existence of relative path.?
  • Andreas Magnusson
    Andreas Magnusson over 10 years
    @PriteshAcharya: boost::filesystem::exists(boost::filesystem::absolute(relati‌​vePath))
  • FelixJongleur42
    FelixJongleur42 over 10 years
    Noticed that good() also yields true if the given argument denotes a directory, see stackoverflow.com/questions/9591036/…
  • Marcel Tricolici
    Marcel Tricolici almost 10 years
    unfortunately boost filesystem cannot be used in windows phone :((
  • HelloWorld
    HelloWorld over 8 years
    I 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
    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
    Rastikan over 8 years
    Good 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
    Michael about 8 years
    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.
  • gsamaras
    gsamaras almost 8 years
    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.
  • pavon
    pavon about 7 years
    Not the downvoter, but the question asked for a cross-platform solution, and stat doesn't exist on all platforms.
  • void.pointer
    void.pointer over 4 years
    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().
  • John
    John over 2 years
    The link is not available any more.