8
votes

I'm using fstream library to work with files. Basically, I need to know if a certain file exists or not. In c++ documentation online, about open(), it reads:

Return Value

none

If the function fails to open a file, the failbit state flag is set for the stream (which may throw ios_base::failure if that state flag was registered using member exceptions).

It says not return value is specified. But in case of failure, a flag is set. My question is that, I should I then access that flag, or to better ask, how should I see if open() is successful or not.

I have this code so far:

int Log::add()
{
    fstream fileStream;

    fileStream.open("logs.txt");
}
4
Then what about flags and exception in case of failure? is_open is used immediately after the open() regularly?Mostafa Talebi
C++ is rather bad in that field. There are two flags: fail and bad which can be tested, but it does not tell you whether the file was protected or did not exist or the path was wrong...Alexis Wilke

4 Answers

15
votes

It says it sets the failbit if the file couldn't be opened. So you can check for that bit:

fileStream.open("logs.txt");
if (fileStream.fail()) {
    // file could not be opened
}

Actually, just if (fileStream) would work here as well, since ios (a base class of ifstream, ofstream, and fstream) has a conversion operator to bool.

Don't worry about the failure exception. You can request exceptions to be thrown on failure by calling ios::exceptions but by default exceptions are not thrown on failure.

Note that this doesn't tell you why the file couldn't be opened. It could be that the file didn't exist, that a directory in the path didn't exist, you don't have permission to open the file, your program has reached the limit on the number of files it can open, and so on. There is no portable way to determine the reason.

6
votes

Note that there are difference between "File exist" and "File can be opened".

To check if file exist (and you indeed do not need to open/read/write the file), use fstat or its c++ counterpart - you don't need any permission to query the info.

Note that if you want to check file exist before open it, you are doing it wrong. Condition may have changed between your checking and the actual attempt to open the file. In general, you just directly open the file with the open/creation options without previously checking.

4
votes

Your method doesn't check for existence, but rather accessibility. It is possible to check existence like this:

#include <sys/stat.h>

inline bool exists (const std::string& filename) {
  struct stat buffer;   
  return (stat (filename.c_str(), &buffer) == 0); 
}

In C++14 it is possible to use this:

#include <experimental/filesystem>

bool exist = std::experimental::filesystem::exists(filename);

& in C++17: (reference)

#include <filesystem>

bool exist = std::filesystem::exists(filename);
2
votes

There are two methods is_open, fail, for example:

string path = "not_exists.txt";
ifstream fin(path);

if(fin.is_open()){
    cout<<"file is open"<<endl;
} else{
    cout<<"file isn't open"<<endl;
}

if(fin.fail()){
    cout<<"file open fail"<<endl;
} else{
    cout<<"file open success"<<endl;
}

output as below:

enter image description here

enter image description here

See: http://www.cplusplus.com/reference/fstream/ifstream/ for reference.