I'm using C++ fstream to read a config file.
#include <fstream>
std::ifstream my_file(my_filename);
Right now, if I pass the path of a directory, it silently ignores this. E.g. my_file.good()
returns true, even if my_filename
is a directory. Since this is unintended input for my program, I like to check for it, and throw an exception.
How do I check if a just opened fstream is a regular file, directory or stream?
I can't seem to find a way to either:
In some forum discussion it was suggested that neither is possible because this is OS-dependant, and thus could never be part of the fstream C++ standard.
The only alternative I can think of is to rewrite my code to get rid of ifstream altogether and resort to the C-method of a file descriptor (*fp
), along with fstat()
:
#include <stdio.h>
#include <sys/stat.h>
FILE *fp = fopen(my_filename.c_str(), "r");
// skip code to check if fp is not NULL, and if fstat() returns != -1
struct stat fileInfo;
fstat(fileno(fp), &fileInfo);
if (!S_ISREG(fileInfo.st_mode)) {
fclose(fp);
throw std::invalid_argument(std::string("Not a regular file ") + my_filename);
}
I prefer fstream. Hence, my question.
void assertGoodFile(const char* fileName) {
ifstream fileOrDir(fileName);
//This will set the fail bit if fileName is a directory (or do nothing if it is already set
fileOrDir.seekg(0, ios::end);
if( !fileOrDir.good()) {
throw BadFile();
};
}