3

This is for a Windows-only program so portable code is not an issue.

I need simply:

bool DoesFileExist( LPWSTR lpszFilename ) { // ... } 
0

12 Answers 12

13

According to the venerable Raymond Chen, you should use GetFileAttributes if you're superstitious.

Sign up to request clarification or add additional context in comments.

4 Comments

interestingly, it looks like _access() is actually just a wrapper around GetFileAttributes() too
@Jay: That's right, since the whole C library is basically implemented in the Windows API.
The only difference between superstition and best practices is if you remember why you do it
+1 for mentioning Raymond. No matter what he said, he is always a good source of information
9

What’s the best way to check if a file exists in C++? (cross platform)

Use _access or stat.

2 Comments

Hey that's cool! I didn't realize you could use those functions on Windows.
They form part of the C runtime (CRT). Visual Studio lets you link to this statically (.lib) or dynamically (in which case a DLL would need to be shipped with your app). I can't think of a reason not to statically link.
7

This is a bit more of a complex question. There is no 100% way to check for existence of a file. All you can check is really "exstistence of a file that I have some measure of access to." With a non-super user account, it's very possible for a file to exist that you have no access to in such a way that access checks will not reveal the existincae of an file.

For instance. It's possible to not have access to a particular directory. There is no way then to determine the existence of a file within that directory.

That being said, if you want to check for the existence of a file you have a measure of access to use one of the following: _stat, _stat64, _stati64, _wstat, _wstat64, _wstati64

Comments

5

GetFileAttributes is what you're looking for. If it returns a value that is not INVALID_FILE_ATTRIBUTES the file exists.

Comments

4

Open it. You can't reliably test if a file exists on a multi-tasking operating system. When you open it you can make sure it doesn't disappear.

1 Comment

Sometimes the goal of testing a file's existence is not to open it. It could be an actual test case.
3

Windows only? Use GetFileAttributes:

bool DoesFileExist( LPWSTR lpszFilename ) { return GetFileAttributes( lpszFilename ) != INVALID_FILE_ATTRIBUTES; } 

Or the more strict version (as per Szere Dyeri's comment):

bool DoesFileExist( LPWSTR lpszFilename ) { return ( ( GetFileAttributes( lpszFilename ) != INVALID_FILE_ATTRIBUTES ) && ( GetLastError() == ERROR_FILE_NOT_FOUND ) ); } 

4 Comments

Make sure GetLastError() == ERROR_FILE_NOT_FOUND
@Szere: Good point, however - depending on usage one may omit it.
This will incorrectly return true when lpszFilename is a directory
a directory is NOT a file, it's part of the file system yes, but the operations that you can perform on it are very different.
1

There are two common ways to do this in Windows code. GetFileAttributes, and CreateFile,

bool DoesFileExist(LPCWSTR pszFilename) { DWORD dwAttrib = GetFileAttributes(pszFilename); if ( ! (dwAttrib & FILE_ATTRIBUTE_DEVICE) && ! (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { return true; } return false; } 

This will tell you a file exists, but but it won't tell you whether you have access to it. for that you need to use CreateFile.

bool DoesFileExist(LPCWSTR pszFilename) { HANDLE hf = CreateFile(pszFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hf) { CloseHandle(hf); return true; } else if (GetLastError() == ERROR_SHARING_VIOLATION) { // should we return 'exists but you can't access it' here? return true; } return false; } 

But remember, that even if you get back true from one of these calls, the file could still not exist by the time you get around to opening it. Many times it's best to just behave as if the file exists and gracefully handle the errors when it doesn't.

1 Comment

Oh come on, return true else return false?
1

Here's one of many options:

HANDLE handle = FindFirstFile(lpszFilename); if (handle == INVALID_HANDLE_VALUE) return false; FindClose(handle); return true; 

Comments

0

I use the FindFirstFile / FindNextFile API functions for this purpose.

Comments

0

In my experience, _access() is simple and fairly portable

#if defined(__MSDOS__) || defined(_Windows) || defined(_WIN32) bool file_exists = _access(file_name,0) == 0; #endif #ifdef unix bool file_exists = _access(file_name,F_OK) == 0; #endif 

Comments

0

This should do it.

#include <fstream> bool DoesFileExist( LPWSTR lpszFilename ) { ifstream fin; fin.open(lpszFilename.c_str(), ifstream::in); fin.close(); return !fin.fail(); } 

1 Comment

What happens here if the file does exist, but you don't have permission to read it?
-1

I usually use boost::filesystem. Has an exists() function. :)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.