在这种情况下,通常只打开一次文件吗?
#!/usr/bin/env perl
use warnings;
use 5.012;
use autodie;
my $file = 'my_file';
open my $fh, '>>', $file;
say $fh "Begin";
close $fh;
$SIG{INT} = sub {
open my $fh, '>>', $file;
say $fh "End";
close $fh;
exit
};
my $result;
while ( 1 ) {
$result++;
# ...
# ...
# ...
open my $fh, '>>', $file;
say $fh $result;
close $fh;
sleep 3;
}
答案 0 :(得分:20)
简短回答:几乎总是,你应该只打开/关闭一次。详情如下。
决定是否这样做取决于4件事:
是否还有其他进程需要写入文件?
如果是这样,您可能需要锁定文件,并且为并发使用而设计的进程的良好行为是尽快释放锁定的共享资源,以便其他人可以获得锁定。
您需要打开多个文件吗?
如果是这样,您可能会用尽打开文件太多的文件句柄,因此您需要关闭。
如果程序崩溃,您在文件中丢失数据的容忍程度。
如果需要将缓冲区中的数据保存到文件中,则需要刷新它。这可以通过频繁关闭来完成,尽管更好的解决方案是在打开文件句柄时频繁刷新或自动刷新。
你是否非常关心在磁盘空间不足后无法关闭文件?
如果是这样,关闭/重新打开文件的次数越多,由于文件系统已满而丢失的数据就越少,因此自上次open
以来您所写的内容都消失了。
在任何其他情况下,只打开/关闭一次(好吧,加上__DIE__
处理程序中的额外关闭和END{}
阻止(大部分时间,你很可能在其他场景中。)
这是因为打开/关闭文件只会毫无理由地浪费系统资源并使代码更长。更具体地说,文件打开和关闭是昂贵的操作,需要系统调用(可能强制从用户区跳转到内核),以及额外的磁盘IO,这是非常昂贵的资源。要验证这一点,请在您的操作系统上运行一些系统利用率测量实用程序,并运行Perl脚本,除了每次打开/关闭10000个不同的文件名外,什么都不做。
请注意(关于方案#3 /#4)如果您非常关心不丢失任何数据,您不应该首先使用文件IO - 使用数据库或消息系统与交付保证。
答案 1 :(得分:4)
对于正常的编程,通常只要您的处理仍然有用,就可以打开每个文件并保留打开的文件句柄。
例外情况是文件处理仅限于代码的特定部分(例如,初始化和关闭),或者特定和相对罕见的事件(与重新读取配置或更新统计或调试相关的信号处理程序)转储)。
在示例中,您显示额外的打开和关闭操作完全是多余的(并且在性能和系统开销方面可能很昂贵)。