提问



有没有比简单地尝试打开文件更好的方法?


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

最佳参考


查找unistd.h中的access()函数。您可以用。替换您的功能


if( access( fname, F_OK ) != -1 ) {
    // file exists
} else {
    // file doesn't exist
}


您也可以使用R_OKW_OKX_OK代替F_OK来检查读取权限,写入权限和执行权限(分别)而不是存在,并且你可以将OR中的任何一个组合在一起(即使用R_OK|W_OK检查读取和写入权限)


更新:请注意,在Windows上,您不能使用W_OK来可靠地测试写入权限,因为访问功能不考虑DACL。access( fname, W_OK )可能会返回0 (成功)因为该文件没有设置只读属性,但您仍然可能没有写入该文件的权限。

其它参考1


像这样使用stat:


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


并称之为:


if (file_exist ("myfile.txt"))
{
  printf ("It exists\n");
}

其它参考2


通常当你想检查一个文件是否存在时,这是因为你想要创建那个文件,如果它没有。 Graeme Perrow的答案很好,如果你想要创建该文件,但如果你这样做,它很容易受到竞争条件:另一个进程可以在你检查它之间创建文件存在,你实际打开它来写它。(不要笑......如果创建的文件是一个符号链接,这可能会有错误安全隐患!)


如果你想检查是否存在和创建文件,如果它不存在,原子,以便没有竞争条件,那么使用:


#include 
#include 

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 */
}

其它参考3


是。使用stat()。见链接。[22]


如果文件不存在,Stat将失败,否则最有可能成功。如果它确实存在,但你对它所在的目录没有读访问权限,它也会失败,但在这种情况下任何方法都会失败(怎么能您是否根据访问权限检查了您可能看不到的目录的内容?简单地说,您可以t。


哦,正如其他人提到的,你也可以使用access()。但是我更喜欢stat(),就好像文件存在一样,它会立即为我提供大量有用的信息(上次更新时间,有多大,拥有该文件的所有者和/或组,访问权限等) 。

其它参考4


从Visual C ++的帮助,我倾向于使用


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

#include  
#include  
#include  

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" );
   }
}


另外值得注意_accesss的模式值(const char * path, int mode )


00仅存在


02写许可


04阅读权限


06读写权限


由于 fopen 在文件存在但无法按要求打开的情况下可能会失败。


编辑:请阅读Mecki的帖子。 stat()确实看起来像一个更简洁的方式。哼哼。

其它参考5


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
        }

其它参考6


我认为在unistd.h中找到的access()函数是Linux的一个很好的选择(你也可以使用stat)。[23] [24]


您可以像这样使用它:


#include 
#include 
#include

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);
    }
}


然后你得到以下输出:


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

其它参考7


您可以使用realpath()函数。


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