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

时间:2018-09-05 06:20:52

标签: c file errno

在Windows 8.1上使用PellesC。

我知道这个主题已经通过许多解决方案得到了解决。我已经阅读了一些解决方案,它们说明了我理解的CreateFilePathFileExistsGetFileAttributes_access的用法。

在对问题Quickest way to check whether or not file exists的回答中,我还阅读了有关比赛条件的重要要点 和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;
}

1 个答案:

答案 0 :(得分:3)

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

文件可能不存在,而您又遇到另一个错误,例如EACCES,因为它无法读取父目录。


另一方面,ENOENT中的fopen并不意味着即使在fopen返回之前或检查{{ 1}},依此类推;这就是C11添加errno标志用于以独占模式打开用于写入的文件的原因-如果文件已经存在,则失败。


总结一下:如果得到x,则在尝试打开该文件时不存在该文件。如果您遇到其他错误,则每个其他错误代码将属于这3个类别之一-可以确定其中任何一个

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

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