有比简单地打开文件更好的方法吗?

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) == 0) {
    // file exists
} else {
    // file doesn't exist
}

在Windows (VC)下,unistd.h不存在。为了使它起作用,有必要定义:

#ifdef WIN32
#include <io.h>
#define F_OK 0
#define access _access
#endif

你也可以使用R_OK, W_OK,和X_OK来代替F_OK来检查读权限,写权限和执行权限(分别)而不是存在,你可以OR它们中的任何一个(即使用R_OK|W_OK来检查读和写权限)

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

其他回答

像这样使用stat:

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

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

像这样叫它:

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

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

你可以这样使用它:

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

你会得到以下输出:

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

在unistd.h中查找access()函数。你可以用

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

在Windows (VC)下,unistd.h不存在。为了使它起作用,有必要定义:

#ifdef WIN32
#include <io.h>
#define F_OK 0
#define access _access
#endif

你也可以使用R_OK, W_OK,和X_OK来代替F_OK来检查读权限,写权限和执行权限(分别)而不是存在,你可以OR它们中的任何一个(即使用R_OK|W_OK来检查读和写权限)

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

通常,当您想要检查一个文件是否存在时,这是因为如果它不存在,您想要创建该文件。如果您不想创建该文件,Graeme Perrow的答案很好,但如果您想创建该文件,那么它很容易受到竞态条件的影响:在您检查它是否存在和您实际打开它并写入它之间,另一个进程可能会创建该文件。(别笑…如果创建的文件是一个符号链接,这可能会有不好的安全隐患!)

如果你想检查文件是否存在,并在它不存在时自动创建文件,这样就没有竞态条件,然后使用这个:

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