在读取模式下使用fopen检查文件的存在不会给出错误。 或/文件名

我正在尝试使用fopen api检查文件的存在。 我期望,如果fopen返回NULL,那么它意味着文件不存在。 我提供file_name作为input命令行参数。

我的代码如下所示:

 FILE *file = NULL; file = fopen(file_name, "rb"); if(file == NULL) { /* file is not found */ } else { /* file is found */ } 

如果我提供。 或/作为file_name然后它接受它作为一个有效的文件名并假装它检测到该文件。 在这种情况下,不应该在Linux上返回NULL吗?

我在Windows上尝试了同样的事情,正如我期待的那样( fopen返回NULL)。

背景:

用户将给path和文件名(一个xml文件)作为应用程序的input选项,然后将通过检查指定path(xml)文件的存在来validation此选项。

用户可以给任何string作为path,所以fopen是足够好的检测它,除非用户input。 或/ – 这些当然不是必需的(XML)文件 – 所以我期待fopen会检测到它作为错误,我们将向用户报告“文件未find”。 但是, fopen接受他们作为有效的文件,当我们尝试处理它时,还有其他一系列的错误。

./是Linux下的目录,它们不是文件,但它们确实存在。

我建议你首先stat文件,以确定它是否存在,如果它是一个正常的文件,而不是其他的东西。 (如目录,设备或硬链接)

检查stat的结果以确定文件类型是否是常规文件。

 #ifdef _WIN32 attr = GetFileAttributes(filename) if (!(attr &= FILE_ATTRIBUTE_DIRECTORY)) { } #elif __linux__ FILE *fp = fopen(filename, "r"); stat buf; int ret = fstat (fp, buf); if ((ret == 0) && (S_ISREG(buf->st_mode))) { // This is a regular file, not something 'odd' } #endif 

GetFileAttrubutes参考:

https://msdn.microsoft.com/zh-cn/library/aa364944%28VS.85%29.aspx https://msdn.microsoft.com/en-us/library/gg258117%28v=vs.85%29的.aspx

在符合POSIX的系统上,如果权限允许,则以读模式打开非硬链接文件( 包括目录)不一定是错误的。

当fopen试图打开一个文件。 它解析文件路径。

你应该知道这个目录也是linux中一种特殊的文件。

如果你只提供“。” (这意味着目前的工作目录)和/意味着根目录。 所以fopen可以成功打开这些目录。 因此它不返回NULL>

我是“我自己”提出明确的检查这个案件:

 if ((strcmp((const char *)file_name, (const char *)".") == 0) || \ (strcmp((const char *)file_name, (const char *)"..") == 0) || \ (strcmp((const char *)file_name, (const char *)"/") == 0) || \ (strcmp((const char *)file_name, (const char *)"\\") == 0) ) /* for windows */ { /* File is not found */ }