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

Is there a better way than simply trying to open the file?

int exists(const char *fname)
{
    FILE *file;
    if ((file = fopen(fname, "r")))
    {
        fclose(file);
        return 1;
    }
    return 0;
}

This question is related to c filesystems cross-platform

The answer is


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
}

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.


Yes. Use stat(). See the man page forstat(2).

stat() will fail if the file doesn't exist, otherwise most likely succeed. If it does exist, but you have no read access to the directory where it exists, it will also fail, but in that case any method will fail (how can you inspect the content of a directory you may not see according to access rights? Simply, you can't).

Oh, as someone else mentioned, you can also use access(). However I prefer stat(), as if the file exists it will immediately get me lots of useful information (when was it last updated, how big is it, owner and/or group that owns the file, access permissions, and so on).


Usually when you want to check if a file exists, it's because you want to create that file if it doesn't. Graeme Perrow's answer is good if you don't want to create that file, but it's vulnerable to a race condition if you do: another process could create the file in between you checking if it exists, and you actually opening it to write to it. (Don't laugh... this could have bad security implications if the file created was a symlink!)

If you want to check for existence and create the file if it doesn't exist, atomically so that there are no race conditions, then use this:

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}

Use stat like this:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

and call it like this:

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}

Yes. Use stat(). See the man page forstat(2).

stat() will fail if the file doesn't exist, otherwise most likely succeed. If it does exist, but you have no read access to the directory where it exists, it will also fail, but in that case any method will fail (how can you inspect the content of a directory you may not see according to access rights? Simply, you can't).

Oh, as someone else mentioned, you can also use access(). However I prefer stat(), as if the file exists it will immediately get me lots of useful information (when was it last updated, how big is it, owner and/or group that owns the file, access permissions, and so on).


Usually when you want to check if a file exists, it's because you want to create that file if it doesn't. Graeme Perrow's answer is good if you don't want to create that file, but it's vulnerable to a race condition if you do: another process could create the file in between you checking if it exists, and you actually opening it to write to it. (Don't laugh... this could have bad security implications if the file created was a symlink!)

If you want to check for existence and create the file if it doesn't exist, atomically so that there are no race conditions, then use this:

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}

Use stat like this:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

and call it like this:

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}

From the Visual C++ help, I'd tend to go with

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

Also worth noting mode values of _access(const char *path,int mode):

  • 00: Existence only

  • 02: Write permission

  • 04: Read permission

  • 06: Read and write permission

As your fopen could fail in situations where the file existed but could not be opened as requested.

Edit: Just read Mecki's post. stat() does look like a neater way to go. Ho hum.


I think that access() function, which is found in unistd.h is a good choice for Linux (you can use stat too).

You can Use it like this:

#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>

void fileCheck(const char *fileName);

int main (void) {
    char *fileName = "/etc/sudoers";

    fileCheck(fileName);
    return 0;
}

void fileCheck(const char *fileName){

    if(!access(fileName, F_OK )){
        printf("The File %s\t was Found\n",fileName);
    }else{
        printf("The File %s\t not Found\n",fileName);
    }

    if(!access(fileName, R_OK )){
        printf("The File %s\t can be read\n",fileName);
    }else{
        printf("The File %s\t cannot be read\n",fileName);
    }

    if(!access( fileName, W_OK )){
        printf("The File %s\t it can be Edited\n",fileName);
    }else{
        printf("The File %s\t it cannot be Edited\n",fileName);
    }

    if(!access( fileName, X_OK )){
        printf("The File %s\t is an Executable\n",fileName);
    }else{
        printf("The File %s\t is not an Executable\n",fileName);
    }
}

And you get the following Output:

The File /etc/sudoers    was Found
The File /etc/sudoers    cannot be read
The File /etc/sudoers    it cannot be Edited
The File /etc/sudoers    is not an Executable

I can't remember where I got this from that I used in my assignment (I usually copy paste the URL where I found it as an easy form of citation) and I cannot decipher what the trailing (file) = 0 is although my best guess is that it is redundancy to set any references to file to 0.

#define fclose(file)  ((file) ? fclose(file) : 0, (file) = 0)

file if a pointer declared as:

FILE *file=NULL;

Yes. Use stat(). See the man page forstat(2).

stat() will fail if the file doesn't exist, otherwise most likely succeed. If it does exist, but you have no read access to the directory where it exists, it will also fail, but in that case any method will fail (how can you inspect the content of a directory you may not see according to access rights? Simply, you can't).

Oh, as someone else mentioned, you can also use access(). However I prefer stat(), as if the file exists it will immediately get me lots of useful information (when was it last updated, how big is it, owner and/or group that owns the file, access permissions, and so on).


From the Visual C++ help, I'd tend to go with

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

Also worth noting mode values of _access(const char *path,int mode):

  • 00: Existence only

  • 02: Write permission

  • 04: Read permission

  • 06: Read and write permission

As your fopen could fail in situations where the file existed but could not be opened as requested.

Edit: Just read Mecki's post. stat() does look like a neater way to go. Ho hum.


Usually when you want to check if a file exists, it's because you want to create that file if it doesn't. Graeme Perrow's answer is good if you don't want to create that file, but it's vulnerable to a race condition if you do: another process could create the file in between you checking if it exists, and you actually opening it to write to it. (Don't laugh... this could have bad security implications if the file created was a symlink!)

If you want to check for existence and create the file if it doesn't exist, atomically so that there are no race conditions, then use this:

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}

From the Visual C++ help, I'd tend to go with

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

Also worth noting mode values of _access(const char *path,int mode):

  • 00: Existence only

  • 02: Write permission

  • 04: Read permission

  • 06: Read and write permission

As your fopen could fail in situations where the file existed but could not be opened as requested.

Edit: Just read Mecki's post. stat() does look like a neater way to go. Ho hum.


FILE *file;
    if((file = fopen("sample.txt","r"))!=NULL)
        {
            // file exists
            fclose(file);
        }
    else
        {
            //File not found, no memory leak since 'file' == NULL
            //fclose(file) would cause an error
        }

Use stat like this:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

and call it like this:

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}

Usually when you want to check if a file exists, it's because you want to create that file if it doesn't. Graeme Perrow's answer is good if you don't want to create that file, but it's vulnerable to a race condition if you do: another process could create the file in between you checking if it exists, and you actually opening it to write to it. (Don't laugh... this could have bad security implications if the file created was a symlink!)

If you want to check for existence and create the file if it doesn't exist, atomically so that there are no race conditions, then use this:

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}

You can use realpath() function.

resolved_file = realpath(file_path, NULL);
if (!resolved_keyfile) {
   /*File dosn't exists*/
   perror(keyfile);
   return -1;
}

FILE *file;
    if((file = fopen("sample.txt","r"))!=NULL)
        {
            // file exists
            fclose(file);
        }
    else
        {
            //File not found, no memory leak since 'file' == NULL
            //fclose(file) would cause an error
        }

Use stat like this:

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

and call it like this:

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}

From the Visual C++ help, I'd tend to go with

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

Also worth noting mode values of _access(const char *path,int mode):

  • 00: Existence only

  • 02: Write permission

  • 04: Read permission

  • 06: Read and write permission

As your fopen could fail in situations where the file existed but could not be opened as requested.

Edit: Just read Mecki's post. stat() does look like a neater way to go. Ho hum.


You can use realpath() function.

resolved_file = realpath(file_path, NULL);
if (!resolved_keyfile) {
   /*File dosn't exists*/
   perror(keyfile);
   return -1;
}

I can't remember where I got this from that I used in my assignment (I usually copy paste the URL where I found it as an easy form of citation) and I cannot decipher what the trailing (file) = 0 is although my best guess is that it is redundancy to set any references to file to 0.

#define fclose(file)  ((file) ? fclose(file) : 0, (file) = 0)

file if a pointer declared as:

FILE *file=NULL;

Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to filesystems

Get an image extension from an uploaded file in Laravel Notepad++ cached files location No space left on device How to create a directory using Ansible best way to get folder and file list in Javascript Exploring Docker container's file system Remove directory which is not empty GIT_DISCOVERY_ACROSS_FILESYSTEM not set Trying to create a file in Android: open failed: EROFS (Read-only file system) Node.js check if path is file or directory

Examples related to cross-platform

How to execute XPath one-liners from shell? iOS / Android cross platform development How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor? What is "stdafx.h" used for in Visual Studio? How to identify platform/compiler from preprocessor macros? How to get the home directory in Python? How to check if running in Cygwin, Mac or Linux? Automatically add all files in a folder to a target using CMake? How is Java platform-independent when it needs a JVM to run? Difference between "\n" and Environment.NewLine