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

后端 未结 9 1292
眼角桃花
眼角桃花 2020-11-22 04:34

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

int exists(const char *fname)
{
    FILE *file;
    if ((file = fopen(fname, \"r\")))
    {
               


        
相关标签:
9条回答
  • 2020-11-22 05:14

    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.

    0 讨论(0)
  • 2020-11-22 05:14

    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
    
    0 讨论(0)
  • 2020-11-22 05:24

    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 */
    }
    
    0 讨论(0)
提交回复
热议问题