Perlでファイルを閉じない場合、どの程度深刻ですか?同じプログラムで再度アクセスした場合、プログラムまたはファイルに影響しますか?
3 に答える
グローバルファイルハンドルは、プログラムが終了するまで残ります。これは悪いことかもしれませんが、とにかくグローバルファイルハンドルを使用するべきではないので、これは問題ではありません。
スコープが残されている場合、または参照カウントがゼロに低下した場合、の字句ファイルハンドルmy
はclose
dです。
ファイルハンドルの名前が再利用される場合、前のファイルハンドルはclose
暗黙的にdになります。次のスクリプトは、同じファイルハンドルを再利用して、任意の数のファイルの最初の5行を出力します。
my $fh;
foreach my $filename (@ARGV) {
open $fh, "<", $filename or die "Can't open $filename"; # $fh is re-used
print scalar <$fh> // next for 1 .. 5; # // is the defined-or
}
ファイルを操作する場合、FHを明示的に閉じることは重要ではありません。ただし、IPCを実行する場合は重要です。パイプへの書き込み端を閉じると、読み取り端へのEOFが示されます。
ingするときfork
は、フォーク中に複製されるため、未使用のファイルハンドルをすべて閉じる必要があります。これは、同じパイプが関連するプロセスでまだ開いているため、1つのプロセスでパイプを閉じると目的のEOFが送信されない可能性があることを意味します。
close
IPCでの重要性を示すプログラムは次のとおりです。
pipe my $out, my $in or die $!;
if (fork()) { # PARENT
close $out; # close unused handle (important!)
select $in;
$| = 1; # set $in to autoflushed (important!)
$SIG{PIPE} = sub {die "Parent"}; # die, when the pipe is closed
print ++$i, "\n" and sleep 1 while 1; # print one number per second
} else { # CHILD
close $in; # close unused handle
print scalar <$out> for 1 .. 5; # read numbers 1 to 5 from the pipe
close $out; # close the pipe (and trigger SIGPIPE)
sleep 5; # wait, then exit
die "Child";
}
このプログラムの出力は1から5までの数字です。次に、子はパイプの端を閉じSIGPIPE
、親でトリガーします。親が死ぬ間、子供も死ぬまで5秒間長居します。
これは、親がパイプの読み取り端を閉じたために機能します。close $out
が親から削除された場合、SIGPIPE
はトリガーされず、プログラムは無限に番号を出力します。
ファイルを閉じないと、プログラムで空きファイル記述子が不足する可能性があります。
男perlfunc:
close
Closes the file or pipe associated with the filehandle, flushes the IO
buffers, and closes the system file descriptor.
一部の出力エラーは、ファイルが閉じられるまで遅延する場合があります。したがって、通常はファイルを閉じて戻り値を確認することをお勧めします。のように
# open (my $fd, ">", $fname) somewhere upstream
close $fd
or die "Couldn't finish writing to $fname: $!";
それ以外は、プログラムは終了時にグローバルファイルハンドルを閉じ、スコープを離れるたびに字句ハンドルを閉じます。