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

Jaz*_*azz 3 c file errno

在 Windows 8.1 上使用 PellesC。

我知道这个话题已经被讨论过很多次并有很多解决方案。CreateFile我已经阅读了说明、PathFileExists、的用法的解决方案GetFileAttributes,_access我有些理解。

我还在问题“检查文件是否存在的最快方法” 和“检查 C 中文件是否存在的最佳方法”的答案中阅读了有关竞争条件的重要观点。(跨平台)。

因此,如果我使用 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;
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ala 6

fopen在打开文件之前需要做很多事情并检查。ENOENT 暗示该文件不存在,但文件不存在并不意味着ENOENT。

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


另一方面,ENOENTfrom并不意味着其他进程甚至在返回之前或在您检查之前都fopen无法创建该文件,等等;这就是为什么 C11 添加了打开文件以在独占模式下写入的标志- 如果文件已存在则失败。fopenerrnox


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

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

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