75

I want to open a file for reading. However, in the context of this program, it's OK if the file doesn't exist, I just move on. I want to be able to identify when the error is "file not found" and when the error is otherwise. Otherwise means I need to quit and error.

I don't see an obvious way to do this with fstream.


I can do this with C's open() and perror(). I presumed that there was a fstream way to do this as well.

0

9 Answers 9

99

EDIT: I've been notified that this does not necessarily indicate a file does not exist, as it may be flagged due to access permissions or other issues as well.

I know I'm extremely late in answering this, but I figured I'd leave a comment anyway for anyone browsing. You can use ifstream's fail indicator to tell if a file exists.

ifstream myFile("filename.txt"); if(myFile.fail()){ //File does not exist code here } //otherwise, file exists 
Sign up to request clarification or add additional context in comments.

2 Comments

What you suggest is NOT a way to check for "file not found". fail() does not indicate "file does not exist", it just indicates "something is wrong". In your particular example it can be "access denied" or "sharing violation" etc.
Very good point, I didn't even consider that. I'll modify the response so that people are aware.
48

I don't think you can know if "the file doesn't exist". You could use is_open() for generic checking:

ofstream file(....); if(!file.is_open()) { // error! maybe the file doesn't exist. } 

If you are using boost you could use boost::filesystem:

#include <boost/filesystem.hpp> int main() { boost::filesystem::path myfile("test.dat"); if( !boost::filesystem::exists(myfile) ) { // what do you want to do if the file doesn't exist } } 

5 Comments

it is not ofstream but ifstream!
Note that both ways check something else: the file may well be there but you might not have the necessary permissions...
Isn't this an inherently racy solution?
From this thread, there's also the file.good() option, which I think is more appropriate here.
boost::filesystem::exists has been added in C++17 as std::filesystem::exists.
26

Since the result of opening a file is OS-specific, I don't think standard C++ has any way to differentiate the various types of errors. The file either opens or it doesn't.

You can try opening the file for reading, and if it doesn't open (ifstream::is_open() returns false), you know it either doesn't exist or some other error happened. Then again, if you try to open it for writing afterwards and it fails, that might fall under the "something else" category.

3 Comments

Sure it's OS-specific, but if C can do it, why can't C++? C would set errno to ENOENT as distinct from EACCESS or other errors.
My answer was in relation to the standard C++ library. If you're calling OS-specific libraries that's not really C++ providing the feature. You're just calling OS-specific libraries from C++.
I was trying to say that there's room in a language for OS-agnostic ways of doing this (such as fopen from the C standard library). C++ may not currently expose such a thing, but there's no reason it couldn't or shouldn't. I was mostly responding to a vague sense of "this is the way it has to be" that I got from your answer's phrasing.
9

A simple way from http://www.cplusplus.com/forum/general/1796/

ifstream ifile(filename); if (ifile) { // The file exists, and is open for input } 

1 Comment

in case anyone else is wondering: According to the documentation, this is identical to !ifile.fail(). if(!ifile) is equivalent to ifile.fail().
6

You can use stat, which should be portable across platforms and is in the standard C library:

#include <sys/stat.h> bool FileExists(string filename) { struct stat fileInfo; return stat(filename.c_str(), &fileInfo) == 0; } 

If stat returns 0, the file (or directory) exists, otherwise it doesn't. I assume that you'll have to have access permissions on all directories in the file's path. I haven't tested portability, but this page suggests it shouldn't be an issue.

3 Comments

Should explictly check return code, as it may be non-zero for reasons other than file doesn't exist. See pubs.opengroup.org/onlinepubs/009695399/functions/stat.html
This is a WRONG thing to do, because during the time AFTER stat() returned and BEFORE fstream's open() got to actually opening a file the file may have been already gone (deleted by another process in the system).
4

A better way:

std::ifstream stream; stream.exceptions(std::ifstream::failbit | std::ifstream::badbit); stream.open(fileName, std::ios::binary); 

1 Comment

Please add some explaination/references.
-1

With C++17 you can use std::filesystem::exists.

Comments

-1
if (!fs::exists(fileName)) { // error! file doesn't exist. } 

Comments

-7

Straight way without creating ifstream object.

if (!std::ifstream(filename)) { // error! file doesn't exist. } 

1 Comment

This creates an ifstream object, just one that goes out of scope as soon as the if statement is finished

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.