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

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

在Windows 8.1上使用PellesC。

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

在回答问题的最快方式中,我还阅读了有关比赛条件的重要信息。
和什么是检查文件是否存在于C中的最佳方法? (跨平台)。

因此,如果我在C中使用fopen()打开文件,并且该文件失败(由于任何原因)并将NULL传递回; 那么我可以进一步检查errno == ENOENT并对其满意,并正确报告该文件不存在。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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...
"
, 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
%s
"
, 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,因为它无法读取父目录。

另一方面,fopen中的ENOENT并不意味着即使在fopen返回之前或检查errno之前,其他某些进程也无法创建文件;这就是C11添加x标志用于打开文件以独占模式进行写入的原因-如果文件已存在则失败。

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

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

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