Because C++ is also tagged, I would use boost::filesystem
:
#include <boost/filesystem.hpp>
bool FileExist( const std::string& Name )
{
return boost::filesystem::exists(Name);
}
Behind the scenes
Apparently, boost is using stat
on POSIX and DWORD attr(::GetFileAttributesW(FileName));
on Windows (Note: I've extracted the relevant parts of code here, it could be that I did something wrong, but this should be it).
Basically, besides return value, boost is checking errno value in order to check if file really does not exist, or your stat failed for a different reason.
#ifdef BOOST_POSIX_API
struct stat path_stat;
if (::stat(p.c_str(), &path_stat)!= 0)
{
if (ec != 0) // always report errno, even though some
ec->assign(errno, system_category()); // errno values are not status_errors
if (not_found_error(errno))
{
return fs::file_status(fs::file_not_found, fs::no_perms);
}
if (ec == 0)
BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
p, error_code(errno, system_category())));
return fs::file_status(fs::status_error);
}
#else
DWORD attr(::GetFileAttributesW(p.c_str()));
if (attr == 0xFFFFFFFF)
{
int errval(::GetLastError());
if (not_found_error(errval))
{
return fs::file_status(fs::file_not_found, fs::no_perms);
}
}
#endif
not_found_error
is defined separately for Windows and for POSIX:
Windows:
bool not_found_error(int errval)
{
return errval == ERROR_FILE_NOT_FOUND
|| errval == ERROR_PATH_NOT_FOUND
|| errval == ERROR_INVALID_NAME // "tools/jam/src/:sys:stat.h", "//foo"
|| errval == ERROR_INVALID_DRIVE // USB card reader with no card inserted
|| errval == ERROR_NOT_READY // CD/DVD drive with no disc inserted
|| errval == ERROR_INVALID_PARAMETER // ":sys:stat.h"
|| errval == ERROR_BAD_PATHNAME // "//nosuch" on Win64
|| errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32
}
POSIX:
bool not_found_error(int errval)
{
return errno == ENOENT || errno == ENOTDIR;
}