Reputation: 11647
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.
Upvotes: 38
Views: 89448
Reputation: 4386
ifstream::good()
Here is an example of what using the fstream
member function looks like:
bool fileExists(const char *fileName)
{
ifstream inFile(fileName);
return inFile.good();
}
The method is short and portable. When the code base is simple this is a good solution to use (no pun intended).
Upvotes: 42
Reputation: 6052
Below is one of my favorite tuck-away functions I keep on hand for multiple uses:
#include <sys/stat.h>
/**
* File Exist Function
*
* @desc Check if a file exists
*
* @param filename - the name of the file to check
*
* @return 'true' if it exist, otherwise returns false.
* */
bool fileExists(const std::string& filename){
struct stat buf;
if (stat(filename.c_str(), &buf) != -1){ return true; }
return false;
}
I find this solution to be much more tasteful than trying to open a file when you don't intend to stream in or out of it.
Upvotes: 72
Reputation: 8758
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
.
Upvotes: 6
Reputation: 1864
One of the way would be to do stat()
and check on errno
.
A sample code would look look this:
#include <sys/stat.h>
using namespace std;
// some lines of code...
int fileExist(const string &filePath) {
struct stat statBuff;
if (stat(filePath.c_str(), &statBuff) < 0) {
if (errno == ENOENT) return -ENOENT;
}
else
// do stuff with file
}
This works irrespective of the stream. If you still prefer to check using ofstream
just check using is_open()
.
Example:
ofstream fp.open("<path-to-file>", ofstream::out);
if (!fp.is_open())
return false;
else
// do stuff with file
Hope this helps. Thanks!
Upvotes: 2
Reputation: 52957
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.
Upvotes: 10