errno == ENOENT 是否足以检查 C 中是否存在文件?

Will errno == ENOENT be a sufficient check to check if file exists in C?

在 Windows 8.1.

上使用 PellesC

我知道这个主题已经用很多解决方案解决了很多次。我已经阅读了说明 CreateFilePathFileExistsGetFileAttributes_access 用法的解决方案,我有点理解。

我在问题的回答中也读到了关于竞争条件的重要观点 What's the best way to check if a file exists in C? (cross platform).

因此,如果我在 C 中使用 fopen() 打开一个文件,当它失败(出于任何原因)并返回 NULL 时;那么我是否可以进一步检查 errno == ENOENT 并对此感到满意并正确报告该文件不存在。

#include <stdio.h>
#include <string.h>
#include <errno.h>

int file_exists(char filename[]) {
    int err = 0; //copy of errno at specific instance
    int r = 0;   //1 for exists and 0 for not exists
    FILE *f = NULL;

    //validate
    if (filename == NULL) {
        puts("Error: bad filename.");
        return 0;
    }

    printf("Checking if file %s exists...\n", filename);

    //check
    errno = 0;
    f = fopen(filename, "r");
    err = errno;
    if (f == NULL) {
        switch (errno) {
          case ENOENT:
            r = 0;
            break;
          default:
            r = 1;
        }
        printf("errno = %d\n%s\n", err, strerror(err));
    } else {
        fclose(f);
        r = 1;
    }

    if (r == 0) {
        puts("It does not.");
    } else {
        puts("It does.");
    }

    return r;
}

fopen 在打开文件之前需要做很多事情和检查。 ENOENT 暗示文件不存在,但是文件不存在并不暗示ENOENT.

一个文件可能不存在并且你得到另一个错误,例如 EACCES 无法读取父目录。


另一方面,来自 fopenENOENT 并不意味着某些其他进程甚至在 fopen returns 之前或您之前就无法创建该文件'正在检查 errno 等等;这就是为什么 C11 添加 x 标志以在独占模式下打开文件以进行 写入 - 如果文件已经存在则失败。


总结一下:如果您得到 ENOENT,当您尝试打开文件时文件不存在。如果您遇到其他错误,那么每个其他错误代码都属于这 3 个中的一个 类 - 可以肯定的是

  • 文件存在,或者
  • 不可能存在
  • 或者当时可能已经存在

打开时。如何处理这些其他错误取决于您和您所需的逻辑。一个简单的方法是拒绝继续处理,并向用户报告错误。