std::ofstream, check if file exists before writing
Solution 1
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.
Solution 2
bool fileExists(const char *fileName)
{
ifstream infile(fileName);
return infile.good();
}
This method is so far the shortest and most portable one. If the usage is not very sophisticated, this is one I would go for. If you also want to prompt a warning, I would do that in the main.
Solution 3
fstream file;
file.open("my_file.txt", ios_base::out | ios_base::in); // will not create file
if (file.is_open())
{
cout << "Warning, file already exists, proceed?";
if (no)
{
file.close();
// throw something
}
}
else
{
file.clear();
file.open("my_file.txt", ios_base::out); // will create if necessary
}
// do stuff with file
Note that in case of an existing file, this will open it in random-access mode. If you prefer, you can close it and reopen it in append mode or truncate mode.
Solution 4
With std::filesystem::exists
of C++17:
#include <filesystem> // C++17
#include <iostream>
namespace fs = std::filesystem;
int main()
{
fs::path filePath("path/to/my/file.ext");
std::error_code ec; // For using the noexcept overload.
if (!fs::exists(filePath, ec) && !ec)
{
// Save to file, e.g. with std::ofstream file(filePath);
}
else
{
if (ec)
{
std::cerr << ec.message(); // Replace with your error handling.
}
else
{
std::cout << "File " << filePath << " does already exist.";
// Handle overwrite case.
}
}
}
See also std::error_code
.
In case you want to check if the path you are writing to is actually a regular file, use std::filesystem::is_regular_file
.
Solution 5
Try ::stat()
(declared in <sys/stat.h>
)
heroddaji
Updated on June 19, 2020Comments
-
heroddaji almost 4 years
I am implementing file saving functionality within a Qt application using C++.
I am looking for a way to check to see if the selected file already exists before writing to it, so that I can prompt a warning to the user.
I am using an
std::ofstream
and I am not looking for a Boost solution. -
Chris Smith almost 13 years+1 for an example using stat instead of opening a file just to close it.
-
Matt Phillips about 11 years+1 but
return stat(filename.c_str(), &buf) != 1;
is rather more compact. -
Schroeder about 11 yearsI timed these on a 2.67GHz Intel Xeon. The stat method above took 0.93 microseconds to confirm that a 500MB file existed. The ifstream methods below took 17.4 microseconds on the same file. To tell that no file exists, stat took 0.72 microseconds, ifstream took 2.4 microseconds.
-
Steve over 10 years@MattPhillips: But that doesn't seem to have the desired effect.
-
Gurgadurgen about 10 years@Steve: Apart from the fact that Matt Phillips' code didn't declare the struct (I assume he meant it to be implied), and the fact that he used
!= 1
rather than!= -1
, why wouldn't it have the same effect? -
grubs almost 10 yearsExplanation: Uses the ifstream constructor to attempt to open the file for reading. When the function returns and the ifstream goes out of scope its destructor will implicitly close the file (in the event that the file existed and the open succeeded).
-
Kong Chun Ho over 7 yearsI think he meant
bool fileExists(const std::string& filename) { struct stat buf; return (stat(filename.c_str(), &buf) != -1); }
-
Lightness Races in Orbit about 7 yearsIs there a reason for the use of the
struct
keyword? It's not necessary in C++, unless there is some name conflict inside the C header that I'm not aware of? -
SasQ over 5 yearsExcept that it does the wrong thing: it checks if a file can be opened, not if it exists. If access permissions disallow the user to access it, this function will erroneously claim that the file does not exist, because it will be unable to open it for reading.
-
SasQ over 5 yearsThink on what would happen if the file exists, but the user doesn't have access permissions to read it.
-
HighCommander4 about 5 years@SasQ: Yeah... this is definitely a hack / workaround. The proper solution in C++17 is
std::filesystem::exists()
, or barring that,stat()
. -
John over 2 years@HighCommander4 “ barring that, stat()”? What's that? What do you intend to tell us?
-
HighCommander4 over 2 years@John If your standard library implementation does not support
std::filesystem
yet, you can use thestat()
function from the POSIX API (also supported on Windows)