【问题标题】:C check if file existsC 检查文件是否存在
【发布时间】:2011-04-21 14:10:47
【问题描述】:

在我必须按照 C89 标准执行的项目中,我必须检查文件是否存在。 我该怎么做?

我想用

FILE *file;
if ((file = fopen(fname, "r")) == NULL)
{
  printf("file doesn't exists");
}
return 0;

但我认为可能存在更多情况,然后文件不存在会执行 fopen == NULL。

我该怎么做?我更喜欢不使用包含而不是。

【问题讨论】:

  • 如果fopen() 失败(即返回0),您不必(不能!)关闭文件句柄。如果成功,您必须这样做。
  • 我认为 C89 标准中没有更好的方法。如果您允许 POSIX 或其他标准,请参阅stackoverflow.com/questions/230062/…

标签: c c89


【解决方案1】:

如果您不能在您的环境中使用 stat()(这绝对是更好的方法),只需评估 errno。不要忘记包含 errno.h。

FILE *file;
if ((file = fopen(fname, "r")) == NULL) {
  if (errno == ENOENT) {
    printf("File doesn't exist");
  } else {
    // Check for other errors too, like EACCES and EISDIR
    printf("Some other error occured");
  }
} else {
  fclose(file);
}
return 0;

编辑:忘记将 fclose 包装到 else 中

【讨论】:

  • -1 表示 ENOENT,ENOENT 不像 OP 所要求的那样是标准 C89 的一部分,它的实现已定义并且不保证存在。 C89:“附加的宏定义,以 E 和一个数字或 E 和一个大写字母开头,也可以由实现指定。”
  • 你是对的,这不在标准中(我猜有充分的理由)。如果代码应该 100% 可移植到所有 C89 实现,这不是正确的方法。另一方面,对 ENOENT 的支持是广泛可用的,因此使用上述方法通常不是一个坏主意。除非您的平台当然是一个非常特殊的平台(嵌入式系统等)。如果 fopen 返回 -1 并忽略特定错误,您也可以简单地退出,就像问题中给出的示例一样。
  • +1 表示ENOENT。它符合 POSIX 标准,比使用 stat 更好,因为这可能会导致竞争条件和安全问题。
  • 为什么stat()access()F_OK 更好?
【解决方案2】:

不可能在纯 ISO 标准 C 中检查 certain 的存在。 没有真正好的可移植方法来确定命名文件是否 存在;您可能不得不求助于系统特定的方法。

【讨论】:

    【解决方案3】:

    这不是一个可移植的东西,所以我会给你特定于操作系统的调用。

    在 Windows 中,您使用 GetFileAttributes 并检查是否返回 -1(INVALID_HANDLE 或类似的东西)。

    在 Linux 中,您可以通过 fstat 执行此操作。

    然而,大多数时候,我只是使用文件打开技巧进行测试,或者只是继续使用文件并检查异常 (C++/C#)。

    【讨论】:

      【解决方案4】:

      我想这与系统环境(例如 POSIX 或 BSD)有关,而不是与您使用的 C 语言版本有关。

      在 POSIX 中,有一个 stat() 系统调用可以为您提供有关文件的信息,即使您无法读取它。但是,如果文件位于您没有访问权限的路径中,则无论该文件是否存在,它总是会失败。

      如果您无权访问该路径,则永远无法查看包含的文件。

      【讨论】:

        【解决方案5】:

        您真的要访问该文件吗?支票通常更好 access(filename,F_OK)==0 来自 <unistd.h>,我认为这是一个相当广泛的标准。

        【讨论】:

          猜你喜欢
          • 2016-02-23
          • 2011-04-07
          • 2013-09-19
          • 2013-06-04
          • 2017-04-24
          • 1970-01-01
          • 2021-12-25
          相关资源
          最近更新 更多