【问题标题】:Will errno == ENOENT be a sufficient check to check if file exists in C?errno == ENOENT 是否足以检查文件是否存在于 C 中?
【发布时间】:2018-09-05 06:20:52
【问题描述】:

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

【问题讨论】:

  • 如果您想向用户报告错误原因,那么使用errno 确实是您想要的。如果您想知道文件是否存在,那么缺少ENOENT 并不能保证(例如,您可能会收到另一个错误,例如EPERM,或者该文件可能已被创建作为fopen 调用的一部分,或...)。你能更详细地描述一下你想要达到的目标吗?
  • 我将发布代码。等一下。

标签: c file errno


【解决方案1】:

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

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


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


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

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

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

【讨论】:

    猜你喜欢
    • 2013-09-19
    • 2013-06-04
    • 1970-01-01
    • 2011-04-07
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多