C语言中如何检查文件是否存在但不能读写?

10

可能是重复问题:
在C语言中检查文件是否存在的最佳方法(跨平台)

我想检查一个文件是否存在。我将我的测试文件权限更改为“chmod -r somefile”。但现在它说该文件不存在,即使它确实存在。

所以我认为如果我没有读取权限,我就无法用“fopen r”打开文件。但这意味着没有简单的方法告诉文件是否存在或无法读取/写入?

还是我错过了什么?任何帮助都将非常感激。

谢谢!

int doesFileExist(const char* filename)
{
  FILE* fptr = fopen(filename, "r");
  if (fptr != NULL)
  {
    fclose(fptr);
    printf("File exists\n");
    return 1;
  }
  printf("File doesnt exist\n");
  return 0;
}

更新:感谢各位提供的出色链接和解释!


1
嗯...你有检查过errno吗?编辑:尝试使用以下代码获取一些错误信息:printf("File doesnt exist: %s\n",strerror(errno));不要忘记包含errno.h头文件。 - Jack
这就是我讨厌stdio API的原因,每当你需要做一些非常规操作,比如调整文件大小或移动文件而不是复制并删除旧文件时,你在可移植性方面就会遇到麻烦。 - Thomas
3个回答

20

fopen实际上试图打开文件,如果您没有读取权限,则无法打开文件。为了检查文件是否存在而不打开它,请使用statstat会提供有关文件的元数据,并且仅需要对包含文件的目录具有读取权限,而不需要对文件本身具有读取权限。

int doesFileExist(const char *filename) {
    struct stat st;
    int result = stat(filename, &st);
    return result == 0;
}

如果result不为0,您可以通过检查errno来获得更多信息。如果errnoENOENT,那么文件不存在;如果是ENOTDIR,那么您提供的路径中的部分不是目录;如果是EACCESS,那么您对路径中的一个目录没有读取权限,因此stat无法给您答案,等等。

另外,请注意,如果您使用符号链接(任何类Unix系统或Windows Vista或更高版本),您应该知道您是在查询符号链接还是它指向的文件。如果您调用stat,则正在查询它指向的文件;如果您有一个符号链接dir/link,它指向other/file,则stat将返回有关other/file的结果(通常这是您想要的,因为这就像打开文件一样)。但是,如果您想了解链接本身(例如,您想知道“dir/link是否存在,即使other/file不存在?”),则应使用lstat()

stat()在Windows上作为兼容性包装器工作(他们更喜欢您使用_stat(),并会发出警告),但通常最好使用本机平台API。在Windows上,您应该使用GetFileAttributes()

int doesFileExist(const char *filename) {
    return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}

1

您实际上并没有检查文件是否存在于此处... 您正在检查是否可以使用读取访问权限打开它。 它可能因为其他原因而失败,而不是文件不存在。 正如您所看到的,您可能没有读取权限。 这也可能是文件被锁定。

请参阅此答案:

如何在 C 语言中最好地检查文件是否存在?(跨平台)

它建议使用stat,这在大多数情况下应该有效,除非您没有对文件所在目录具有读取访问权限。


-1
在Linux(以及许多其他系统)中,您可以使用 opendir()和相关函数来列出目录。我猜只读文件会显示出来。其他平台上应该有类似的功能可用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接