10 April 2012

Does the file exist? No easy question.

I shout 'How do I check whether a file exists in C#' and somebody immediately responds 'File dot Exists'.

I shout 'How do I check whether a file exists in C++' and I get no answer.

It is something I can get really frustrated from. C++ is widely regarded as a good and high level language, and I'd like to agree, but in the year 2012 I expect more from a language. How on earth is it possible that experienced C++ developers cannot answer that simple question in a snap? I googled the question, and the answer is far from clear. I have the impression that this is the best method:

#include <sys/stat.h>
bool FileExists(const char* filename)
{
      struct stat buf;
      return (stat(filename, &buf) != -1);
}

Another good option I found was:

#include <fstream>
bool FileExists(const char *filename)
{
 std::ifstream ifs(filename);
 return ifs.is_open();
}

That's almost the same as the previous one and fstream is included more often. However in the first version you're not actually opening the file afaik.

The next one is horrible, it even throws an exception! For a file check! And it's platform dependent.

#include <Windows.h>
bool FileExists(char* filePath)
{
 DWORD fileAtt = GetFileAttributesA(filePath);
 if(fileAtt == INVALID_FILE_ATTRIBUTES)
  throw GetLastError();
 return ( ( fileAtt & FILE_ATTRIBUTE_DIRECTORY ) == 0 ); 
}

There are a bunch of variations of above three circulating on the web. Boost also has a function, so if you use boost you'd probably should use that.

If you do not want to write this function in every cpp where you'd need it, you should put it in a header. If you don't want the name to collide with another existing function with the same name, you should put it in a namespace. You might put it in a library with some other common functions, a toollib or something that you include in all your projects, which means that you need to compile it to various targets, perhaps various platforms. The toollib gets changes in every project, so you need to keep it compatible across projects, or you'll be having various versions of your toollib...

So this is what saddens me. Why is it so hard to have some changes in the language? wouldn't it be ideal if we had

#include <fstream>
...
if(std::ifstream::exists(filename))
{
...

in our code where we want the check. Just as C# has it for example:

...
if(System::IO:File.Exists(filename))
{
...
It would be in the stl, every compiler would implement it as efficient as possible, live would be beautiful.

No comments: