是的,/dev/null
总是可以打开的——除非它不是。
这听起来很傻,但我不是在开玩笑。如果/dev/null
无法打开,您可能有一个严重损坏的、可能处于临界状态的非功能系统——但知道这并不等同于保证文件是可打开的。
打开文件失败总是有原因的。你永远不应该找借口不检查fopen
失败的返回值。
它可能永远不会发生,你知道,它可能永远不会发生在正常运行的系统上,但问问你自己,如果/dev/null
“不可能”打开失败会发生什么?
如果您的程序检查fopen
失败,它将打印一条消息,如"Impossible error! Can't open /dev/null"
,并且很清楚发生了什么。
如果你的程序没有检查fopen
失败,它会在第一次尝试打印某些东西时神秘地崩溃whereToPrint
,你的用户会想知道哪里出了问题。
神秘地崩溃的程序是坏的。告诉你发生了什么的程序很好。
而且,您可以告诉用户发生的事情越多越好。我建议 print "Impossible error! Can't open /dev/null"
,这总比没有好,但它实际上仍然很不完整。您真的应该编写行为如下的代码:
#include <stdio,h>
#include <string.h>
#include <errno.h>
FILE *whereToPrint;
if(strcmp(custom_topic, ERROR_TOPIC) != 0)
whereToPrint = stdout;
else if((whereToPrint = fopen("/dev/null", "w")) == NULL) {
fprintf(stderr, "Impossible error! Can't open /dev/null: %s\n", strerror(errno));
exit(1);
}
现在,在它失败的“不可能”场合,它会告诉你为什么它无法打开/dev/null
,这可能是非常有用的信息。它可能会打印
Impossible error! Can't open /dev/null: No such file or directory
如果/dev/null
不知何故不存在。或者它可能会打印
Impossible error! Can't open /dev/null: Permission denied
如果像其他人建议的那样,有人错误地限制了/dev/null
您系统上的权限。或者它可能会打印
Impossible error! Can't open /dev/null: Too many open files
事实上,即使在正确配置的系统上,由于程序中的错误,它也可能会失败!
例如,回到你的“漂亮的三元运算符”,如果你曾经写过类似的东西
void log_message(const char *msg)
{
FILE *whereToPrint = (strcmp(custom_topic, ERROR_TOPIC) == 0) ?
fopen("/dev/null", "w") : stdout;
fprintf(whereToPrint, "%s", msg);
}
您迟早很可能会收到“打开的文件过多”错误,因为log_message()
我在这里编写的函数当然有一个错误:它每次调用时都会打开文件(可能),但从不关闭它。
三元运算符的“不错”用法——或任何其他“不错”的技巧——写起来很有趣,如果它们有效,它们很好,但请不要以牺牲其他为代价来坚持它们,代码中更重要的方面,例如确保它在所有情况下都能正常工作。:-)