Fastest Way to Check If a File Exists Using Standard C++/C++11,14,17/C

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,



























MethodTime
exists_test0 (ifstream)0.485s
exists_test1 (FILE fopen)0.302s
exists_test2 (posix access())0.202s
exists_test3 (posix stat())0.134s

What's the best way to check if a file exists in C?

Look up the access() function, found in unistd.h. You can replace your function with

if (access(fname, F_OK) == 0) {
// file exists
} else {
// file doesn't exist
}

Under Windows (VC) unistd.h does not exist. To make it work it is necessary to define:

#ifdef WIN32
#include <io.h>
#define F_OK 0
#define access _access
#endif

You can also use R_OK, W_OK, and X_OK in place of F_OK to check for read permission, write permission, and execute permission (respectively) rather than existence, and you can OR any of them together (i.e. check for both read and write permission using R_OK|W_OK)

Update: Note that on Windows, you can't use W_OK to reliably test for write permission, since the access function does not take DACLs into account. access( fname, W_OK ) may return 0 (success) because the file does not have the read-only attribute set, but you still may not have permission to write to the file.

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.

Is there a way to check if virtualisation is enabled on the BIOS using C++?

No, there is no way to detect virtualization support using only standard C++ facilities. The C++ standard library does not have anything related to hardware virtualization. (Its exposure of low level details like that is extremely limited.)

You would need to use OS-specific facilities to detect this.

Check if file exists, otherwise create a new one

Because of TOCTOU races, the best way to do this is to drop down a level and use open, which, unlike fopen, lets you specify "open this file for read and write, preserving existing contents, and create it if it doesn't already exist":

FILE *ensure_file(const char *fname) 
{
int fd = open(fname, O_RDWR | O_CREAT, 0666);
if (fd == -1) {
perror(fname);
return 0;
}
return fdopen(fd, "r+");
}

problem in using fprintf_s(getting warnings) in c

When you try to open a file with fopen_s function, it may or may not succeed, so you must check the return value of that invocation.

If for some reason, the file was not opened, then your file pointer variable, sttp will not be initialized, hence the VS IDE is showing you the warning.

Modify your code, like below.

FILE* sttp;
if(0 == fopen_s(&sttp, "text.txt", "w") )
{
fprintf_s(sttp, "test");
fclose(sttp);
}


Related Topics



Leave a reply



Submit