我正在寻找快速(针对性能关键代码),安全且跨平台的方式来检查FILE*
在成功调用fopen()
之后是否实际指向文件。
用ftell()
询问当前位置是一种方法,但是
我怀疑它是最快,最准确,更安全还是没有更好的直接和专注于这种方式。
答案 0 :(得分:1)
在C中有三种指针值:
fopen
或malloc
(尚未传递给fclose
或free
)。简单的事实是,如果你有一个类型为3的指针,那么语言中就没有机制可以告诉你指针是否有效。如果你有一个指针p
可能是从malloc
获得的,但你不记得了,那么就没有办法让编译器或运行时系统告诉你它当前是否存在指向有效的记忆。如果你有一个FILE指针fp
可能是从fopen
获得的,但是你不记得了,那么就没有办法要求编译器或运行时系统告诉你它是否目前“指向”有效文件。
所以由程序员你来跟踪指针值,并使用编程实践来帮助你确定指针值是否有效。
这些方式包括以下内容:
fopen
或malloc
)时,请始终测试返回值以查看它是否为NULL,如果是,则提前返回或打印错误消息或者任何合适的东西。fclose
或free
或等效指针释放它时,请始终将其设置为NULL。如果你虔诚地做了这三件事,那么你可以通过
来测试指针是否有效if(p != NULL)
或
if(p)
同样地,如果你虔诚地做这些事情,你可以通过做
来测试指针是否无效。if(p == NULL)
或
if(!p)
但如果您已经虔诚地执行了第1步和第3步,那么这些测试只能 。如果还没有,那么各种指针值可能 - 很可能 - 是非NULL但无效。
以上是一种策略。我应该指出,步骤1和3并非绝对必要。另一个策略是虔诚地应用第2步,并且永远不要保持 - 永远不要尝试使用 - 指针可能为空。如果fopen
或malloc
之类的函数返回NULL,则可以立即退出程序,或者立即从您所在的函数返回,通常使用失败代码告诉调用者您无法执行job(因为你无法打开你需要的文件,或者你无法分配你需要的内存)。在一个虔诚地应用规则2的程序中,您甚至不需要测试指针的有效性,因为这些程序中的所有指针值都是有效的。 (好吧,只要规则2被虔诚地应用,所有指针都是有效的。如果你忘记一次应用规则2,事情就会开始崩溃。)
答案 1 :(得分:0)
如果对fopen
的呼叫成功,但您想知道您是否刚刚打开了某个文件或其他内容,我知道两种常规方法:
在文件描述符上使用fstat
(或者在刚打开的同一路径名上使用stat
),然后检查模式位。
尝试搜索文件描述符。如果这按预期工作,它可能是一个文件;如果它不是管道或插座或类似的东西。
(1)的代码可能看起来像
struct stat st;
fstat(fileno(fp), &st);
if(st.st_mode & S_IFMT) == S_IFREG)
/* it's a regular file */
执行(2)我通常寻求偏移1,然后测试看看我的偏移量。如果我在1,它是一个可搜索的文件,我将回退到0,用于该程序的其余部分。但如果我仍然在0,那它不是一个可搜索的文件。 (当然,我在打开文件后立即执行此操作,并将结果记录在与打开文件关联的自己的标记中,因此性能损失很小。)