How to check if a file exists and is readable in C++?

87,457

Solution 1

I would probably go with:

ifstream my_file("test.txt");
if (my_file.good())
{
  // read away
}

The good method checks if the stream is ready to be read from.

Solution 2

You might use Boost.Filesystem. It has a boost::filesystem::exist function.

I don't know how about checking read access rights. You could look in Boost.Filesystem too. However likely there will be no other (portable) way than try to actually read the file.

EDIT (2021-08-26): C++17 introduced <filesystem> and there you have std::filesystem::exists. Boost is no longer needed for this.

Solution 3

if you are on unix then access() can tell you if it's readable. However if ACL's are in use, then it gets more complicated, in this case it's best to just open the file with ifstream and try read.. if you cannot read then the ACL may prohibit reading.

Solution 4

What Operating System/platform?

On Linux/Unix/MacOSX, you can use fstat.

On Windows, you can use GetFileAttributes.

Usually, there is no portable way of doing this with standard C/C++ IO functions.

Solution 5

C++17, cross-platform: Check file existence with std::filesystem::exists and readability with std::filesystem::status & std::filesystem::perms:

#include <iostream>
#include <filesystem> // C++17
namespace fs = std::filesystem;

/*! \return True if owner, group and others have read permission,
            i.e. at least 0444.
*/
bool IsReadable(const fs::path& p)
{
    std::error_code ec; // For noexcept overload usage.
    auto perms = fs::status(p, ec).permissions();
    if ((perms & fs::perms::owner_read) != fs::perms::none &&
        (perms & fs::perms::group_read) != fs::perms::none &&
        (perms & fs::perms::others_read) != fs::perms::none
        )
    {
        return true;
    }
    return false;
}

int main()
{
    fs::path filePath("path/to/test.txt");
    std::error_code ec; // For noexcept overload usage.
    if (fs::exists(filePath, ec) && !ec)
    {
        if (IsReadable(filePath))
        {
            std::cout << filePath << " exists and is readable.";
        }
    }
}

Consider also checking for the file type.

Share:
87,457
Jerry
Author by

Jerry

Updated on July 08, 2022

Comments

  • Jerry
    Jerry almost 2 years

    I've got a fstream my_file("test.txt"), but I don't know if test.txt exists. In case it exists, I would like to know if I can read it, too. How to do that?

    I use Linux.

  • Blindy
    Blindy over 14 years
    Why do you say that, you could always just try to open a file with fopen and if it returns 0 you can deduce portably that the file is nonexistent.
  • xtofl
    xtofl over 14 years
    This way you not only check if it exists & is readable, you actually open it.
  • xtofl
    xtofl over 14 years
    fstat is available on windows, too, in sys/stat.h.
  • Kim Gräsman
    Kim Gräsman over 14 years
    Yeah, that's true. I read the OP's question that the file was already opened anyway, but I could be wrong.
  • bk1e
    bk1e over 14 years
    access() is a great way to introduce time-of-check-to-time-of-use bugs.
  • Richard Corden
    Richard Corden over 14 years
    Does boost filesystem handle very long paths on windows (> 256)? We recently ran into the problem that the non unicode windows API has a maximum of 256 characters.
  • Galadrius Krunthar
    Galadrius Krunthar almost 9 years
    I ran across claims that PathFileExists() is unreliable: mfctips.com/tag/file-exists
  • SasQ
    SasQ about 5 years
    Moreover, it cannot tell whether the file couldn't be opened because it didn't exist or because of access permission problems.
  • SasQ
    SasQ about 5 years
    @Blindy or it does exist, but you don't have permissions to access it. What then? :q Your deduction is wrong.
  • Blindy
    Blindy about 5 years
    @sasq makes no difference, the title literally says "and is readable". A file you don't have permission to access is by definition non-readable. Critical thinking will get you far in life!
  • SasQ
    SasQ about 5 years
    @Blindy I was refering to your comment, not to the title or original post. My point was that opening a file just to check if it exists may have side effects that one does not necessarily desire, including a possibility to accidentally damage the file (e.g. if one opens it for writing as well and it happens that it exists). And spare me the "critical thinking" ad personam.
  • Blindy
    Blindy about 5 years
    Why would you open it for writing if you just tested for its existence and the function returned false? You're running in circles trying to find weird edge cases when in fact this is perfectly fine as it is. You must be an inexperienced student.
  • user14717
    user14717 over 4 years
    Great answer, but quick question: How can we check if this executable has permissions to read the file, rather than who has permissions to read the file?