std::ofstream, check if file exists before writing
This is one of my favorite tuck-away functions I keep on hand for multiple uses.
#include <sys/stat.h>
// Function: fileExists
/**
* Check if a file exists
*
* @param[in] filename - the name of the file to check
*
* @return true if the file exists, else false
*/
bool fileExists(const std::string& filename)
{
struct stat buf;
if (stat(filename.c_str(), &buf) != -1)
{
return true;
}
return false;
}
I find this much more tasteful than trying to open a file if you have no immediate intentions of using it for I/O.
How to check if a file exists in C++ with fstream::open()
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.
How to check if a file exists before creating a new file
Assuming it is OK that the operation is not atomic, you can do:
if (std::ifstream(name))
{
std::cout << "File already exists" << std::endl;
return false;
}
std::ofstream file(name);
if (!file)
{
std::cout << "File could not be created" << std::endl;
return false;
}
...
Note that this doesn't work if you run multiple threads trying to create the same file, and certainly will not prevent a second process from "interfering" with the file creation because you have TOCTUI problems. [We first check if the file exists, and then create it - but someone else could have created it in between the check and the creation - if that's critical, you will need to do something else, which isn't portable].
A further problem is if you have permissions such as the file is not readable (so we can't open it for read) but is writeable, it will overwrite the file.
In MOST cases, neither of these things matter, because all you care about is telling someone that "you already have a file like that" (or something like that) in a "best effort" approach.
Fastest way to check if a file exists using standard C++/C++11,14,17/C?
Well I threw together a test program that ran each of these methods 100,000 times, half on files that existed and half on files that didn't.
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>
inline bool exists_test0 (const std::string& name) {
ifstream f(name.c_str());
return f.good();
}
inline bool exists_test1 (const std::string& name) {
if (FILE *file = fopen(name.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
inline bool exists_test2 (const std::string& name) {
return ( access( name.c_str(), F_OK ) != -1 );
}
inline bool exists_test3 (const std::string& name) {
struct stat buffer;
return (stat (name.c_str(), &buffer) == 0);
}
Results for total time to run the 100,000 calls averaged over 5 runs,
Method | Time |
---|---|
exists_test0 (ifstream) | 0.485s |
exists_test1 (FILE fopen) | 0.302s |
exists_test2 (posix access()) | 0.202s |
exists_test3 (posix stat()) | 0.134s |
How to make sure file exists and it is opened
Simply create a file stream without specifying without telling which file to open.
fstream file;
file.open("data.txt");
Then use .fail()
to check if it has FAILED in opening the file
if (fileStream.fail())
{
ofstream file("data.txt");
}
file.open("data.txt");
Then open it again. fstream (Filestream) is just simply a child of iostream which does not required to be initialized and can be declared you can read more about it over here
ifstream: how to tell if specified file doesn't exist
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.
Related Topics
Opinions on Type-Punning in C++
Delete All Items from a C++ Std::Vector
How to Compile Openssl for X64
Specification of Source Charset Encoding in Msvc++, Like Gcc "-Finput-Charset=Charset"
Member Function with Static Linkage
Qt4: Transparent Window with Rounded Corners
Why Is (Void) 0 a No Operation in C and C++
Is an Object Guaranteed to Be Moved When It Is Returned
Which Greedy Initializer-List Examples Are Lurking in the Standard Library
Template Metaprogram Converting Type to Unique Number
Are Ieee Floats Valid Key Types for Std::Map and Std::Set
How to Find the Name of the Calling Function
What Is "->" After Function Declaration
Benefits of Using Reserve() in a Vector - C++
How to Initialize All Elements in an Array to the Same Number in C++
What Are Potential Dangers When Using Boost::Shared_Ptr
Type Erasure in C++: How Boost::Shared_Ptr and Boost::Function Work