在tchrists broilerplate我发现在END块中明确关闭了STDOUT。
END { close STDOUT }
我知道结束并关闭,但我想知道为什么需要它。
开始搜索时,可在以下perlfaq8中找到:
例如,您可以使用它来制作 确保你的过滤程序设法成功 完成输出而不填满 磁盘:
END {
close(STDOUT) || die "stdout close failed: $!";
}
无论如何都不明白。 :(
有人可以解释(可能有一些代码示例):
答案 0 :(得分:15)
许多系统实施“乐观”文件操作。这意味着调用例如print
应该将一些数据添加到文件可以在数据实际写入文件之前成功返回,或者甚至在磁盘上保留足够的空间以便写入成功之前
在这些情况下,如果磁盘几乎已满,则所有打印都可以显示成功,但是当需要关闭文件并将其刷新到磁盘时,系统会意识到没有剩余空间。关闭文件时会出现错误。
此错误表示您认为保存的所有输出实际上可能根本没有保存(或部分保存)。如果这很重要,您的程序需要报告错误(或尝试纠正这种情况,或......)。
所有这些都可以在STDOUT
文件句柄上发生,如果它连接到文件,例如如果您的脚本以:
perl script.pl > output.txt
如果您输出的数据很重要,并且您需要知道所有数据是否确实写得正确,那么您可以使用您引用的语句来检测问题。例如,在第二个代码段中,如果die
报告错误,则脚本会显式调用close
; tchrist's boilerplate在use autodie
下运行,如果die
失败,则自动调用close
。
(这不能保证数据永久存储在磁盘上,其他因素也会在那里发挥作用,但这是一个很好的错误指示。即如果关闭失败,你知道你有问题。)
答案 1 :(得分:4)
我认为Mat错了。
Perl和系统都有缓冲区。 close
导致 Perl的缓冲区被刷新到系统。它不一定会导致系统的缓冲区像Mat声称的那样写入磁盘。这就是fsync
所做的。
现在,无论如何这都会在退出时发生,但是调用close
可以让你有机会处理冲洗缓冲区时遇到的任何错误。
close
做的另一件事是报告系统尝试将其缓冲区刷新到磁盘时的早期错误。