errno == ENOENT 是否足以检查 C 中是否存在文件?
Will errno == ENOENT be a sufficient check to check if file exists in C?
在 Windows 8.1.
上使用 PellesC
我知道这个主题已经用很多解决方案解决了很多次。我已经阅读了说明 CreateFile
、PathFileExists
、GetFileAttributes
、_access
用法的解决方案,我有点理解。
我在问题的回答中也读到了关于竞争条件的重要观点
和 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;
}
fopen
在打开文件之前需要做很多事情和检查。 ENOENT
暗示文件不存在,但是文件不存在并不暗示ENOENT
.
一个文件可能不存在并且你得到另一个错误,例如 EACCES
无法读取父目录。
另一方面,来自 fopen
的 ENOENT
并不意味着某些其他进程甚至在 fopen
returns 之前或您之前就无法创建该文件'正在检查 errno
等等;这就是为什么 C11 添加 x
标志以在独占模式下打开文件以进行 写入 - 如果文件已经存在则失败。
总结一下:如果您得到 ENOENT
,当您尝试打开文件时文件不存在。如果您遇到其他错误,那么每个其他错误代码都属于这 3 个中的一个 类 - 可以肯定的是
- 文件存在,或者
- 它不可能存在
- 或者当时可能已经存在
打开时。如何处理这些其他错误取决于您和您所需的逻辑。一个简单的方法是拒绝继续处理,并向用户报告错误。
在 Windows 8.1.
上使用 PellesC我知道这个主题已经用很多解决方案解决了很多次。我已经阅读了说明 CreateFile
、PathFileExists
、GetFileAttributes
、_access
用法的解决方案,我有点理解。
我在问题的回答中也读到了关于竞争条件的重要观点
因此,如果我在 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;
}
fopen
在打开文件之前需要做很多事情和检查。 ENOENT
暗示文件不存在,但是文件不存在并不暗示ENOENT
.
一个文件可能不存在并且你得到另一个错误,例如 EACCES
无法读取父目录。
另一方面,来自 fopen
的 ENOENT
并不意味着某些其他进程甚至在 fopen
returns 之前或您之前就无法创建该文件'正在检查 errno
等等;这就是为什么 C11 添加 x
标志以在独占模式下打开文件以进行 写入 - 如果文件已经存在则失败。
总结一下:如果您得到 ENOENT
,当您尝试打开文件时文件不存在。如果您遇到其他错误,那么每个其他错误代码都属于这 3 个中的一个 类 - 可以肯定的是
- 文件存在,或者
- 它不可能存在
- 或者当时可能已经存在
打开时。如何处理这些其他错误取决于您和您所需的逻辑。一个简单的方法是拒绝继续处理,并向用户报告错误。