是的,/dev/null 总是可以打开的——除非它不能打开。
这听起来很傻,但我不是在开玩笑。如果/dev/null 无法打开,您可能有一个严重损坏的、可能处于临界状态的非功能系统——但知道这并不能保证文件是可打开的。
总是打开文件失败的原因。永远不要找借口不检查 fopen 的返回值是否失败。
它可能永远不会发生,你知道,它可能永远不会发生在正常运行的系统上,但问问自己,如果打开 /dev/null“不可能”失败会发生什么?
如果您的程序检查fopen 失败,它将打印类似"Impossible error! Can't open /dev/null" 的消息,并且很清楚发生了什么。
-
如果您的程序未能检查 fopen 故障,它会在第一次尝试将内容打印到 whereToPrint 时神秘地崩溃,您的用户会想知道出了什么问题。
神秘崩溃的程序是坏的。告诉你发生了什么的程序很好。
而且,您越能告诉用户正在发生的事情越好。我建议打印"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() 函数当然有一个错误:它每次都打开文件(可能)它被调用,但从不关闭它。
三元运算符的“不错”用法——或任何其他“不错”的技巧——写起来很有趣,如果它们能工作就很好,但请不要以牺牲为代价坚持它们代码的其他更重要的方面,例如确保它在所有情况下都能正常工作。 :-)