78

How can we check if a file Exists or not using a Win32 program? I am working for a Windows Mobile App.

codaddict
  • 429,241
  • 80
  • 483
  • 523
RK-
  • 11,865
  • 22
  • 88
  • 153

9 Answers9

219

Use GetFileAttributes to check that the file system object exists and that it is not a directory.

BOOL FileExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES && 
         !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

Copied from How do you check if a directory exists on Windows in C?

Community
  • 1
  • 1
Zach Burlingame
  • 13,286
  • 14
  • 54
  • 65
38

You can make use of the function GetFileAttributes. It returns 0xFFFFFFFF if the file does not exist.

Ajay
  • 17,472
  • 10
  • 53
  • 96
codaddict
  • 429,241
  • 80
  • 483
  • 523
29

You can call FindFirstFile.

Here is a sample I just knocked up:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int fileExists(TCHAR * file)
{
   WIN32_FIND_DATA FindFileData;
   HANDLE handle = FindFirstFile(file, &FindFileData) ;
   int found = handle != INVALID_HANDLE_VALUE;
   if(found) 
   {
       //FindClose(&handle); this will crash
       FindClose(handle);
   }
   return found;
}

void _tmain(int argc, TCHAR *argv[])
{
   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Looking for file is %s\n"), argv[1]);

   if (fileExists(argv[1])) 
   {
      _tprintf (TEXT("File %s exists\n"), argv[1]);
   } 
   else 
   {
      _tprintf (TEXT("File %s doesn't exist\n"), argv[1]);
   }
}
cdonts
  • 8,768
  • 2
  • 41
  • 69
Preet Sangha
  • 62,844
  • 17
  • 138
  • 209
18

How about simply:

#include <io.h>
if(_access(path, 0) == 0)
    ...   // file exists
Pierre
  • 3,824
  • 2
  • 33
  • 37
  • Pierre How did you find this function ? any reference ? – Buddhika Chaturanga Jul 03 '18 at 04:38
  • 2
    @Buddhika Chaturanga I started using it in Borland Turbo C, back in the 80's. It was the only way to check for the presence of a file, before the fancier "CreateFile". It's buried in the Visual Studio documentation. – Pierre Jul 04 '18 at 12:43
9

Another option: 'PathFileExists'.

But I'd probably go with GetFileAttributes.

Adrian McCarthy
  • 43,194
  • 15
  • 118
  • 167
  • 2
    In addition `PathFileExists` requires the use of "Shlwapi.dll" (which is unavailable on a few windows versions) and is slightly slower than `GetFileAttributes`. – Bitterblue Apr 05 '13 at 12:45
  • But it doesn't tell you if a file or directory existed. – Jonathan Wood Feb 24 '17 at 21:19
  • BTW, PathFileExists is just a wrapper for GetFileAttributes with additional SetErrorMode(SEM_FAILCRITICALERRORS) wrapper. – Alex Sep 09 '19 at 17:17
0

You can try to open the file. If it failed, it means not exist in most time.

fanzhou
  • 97
  • 1
  • 5
  • I'd go with CreateFile -> CloseHandle. easiest and cheapest. – OSH Jun 18 '13 at 19:34
  • 5
    A file open can also fail if the files exists but the user does not have sufficient privileges to open the file. These days, that's a **very** common situation. – JackLThornton Apr 15 '16 at 23:39
  • Not to mention it is not the cheapest because the file can be on a network share which adds latency for each call and with CloseHandle you have two calls instead of one. – Igor Levicki Nov 22 '19 at 10:37
0

Came across the same issue and found this brief code in another forum which uses GetFileAttributes Approach

DWORD dwAttr = GetFileAttributes(szPath);
if (dwAttr == 0xffffffff){

  DWORD dwError = GetLastError();
  if (dwError == ERROR_FILE_NOT_FOUND)
  {
    // file not found
  }
  else if (dwError == ERROR_PATH_NOT_FOUND)
  {
    // path not found
  }
  else if (dwError == ERROR_ACCESS_DENIED)
  {
    // file or directory exists, but access is denied
  }
  else
  {
    // some other error has occured
  }

}else{

  if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
  {
    // this is a directory
  }
  else
  {
    // this is an ordinary file
  }
}

where szPath is the file-path.

A5H1Q
  • 170
  • 2
  • 12
0

Use OpenFile with uStyle = OF_EXIST

if (OpenFile(path, NULL, OF_EXIST) == HFILE_ERROR)
{
    // file not found
}
// file exists, but is not open

Remember, when using OF_EXIST, the file is not open after OpenFile succeeds. Per Win32 documentation:

Value Meaning
OF_EXIST (0x00004000) Opens a file and then closes it. Use this to test for the existence of a file.

See doc: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfile

srpax
  • 21
  • 6
-2

Another more generic non-windows way:

static bool FileExists(const char *path)
{
    FILE *fp;
    fpos_t fsize = 0;

    if ( !fopen_s(&fp, path, "r") )
    {
        fseek(fp, 0, SEEK_END);
        fgetpos(fp, &fsize);
        fclose(fp);
    }

    return fsize > 0;
}
Alturis
  • 74
  • 8
  • if you're going to use fopen et al. you may as well just use `_access(0)`. – Rob K Jun 22 '16 at 14:10
  • 1
    @RobK This has the minor advantage of being cross-platform whereas _access is not. The real problem is that it will return that zero-length files don't exist... – Perkins Sep 05 '18 at 19:00
  • fopen_s is Microsoft specific, and in addition to 0 byte files being declared non-existing by this broken code it also fails on files it can't open (permissions, sharing). – Igor Levicki Nov 22 '19 at 10:39