6

Perlでファイルを閉じない場合、どの程度深刻ですか?同じプログラムで再度アクセスした場合、プログラムまたはファイルに影響しますか?

4

3 に答える 3

13

グローバルファイルハンドルは、プログラムが終了するまで残ります。これは悪いことかもしれませんが、とにかくグローバルファイルハンドルを使用するべきではないので、これは問題ではありません。

スコープが残されている場合、または参照カウントがゼロに低下した場合、の字句ファイルハンドルmyclosedです。

ファイルハンドルの名前が再利用される場合、前のファイルハンドルは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が送信されない可能性があることを意味します。

closeIPCでの重要性を示すプログラムは次のとおりです。

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はトリガーされず、プログラムは無限に番号を出力します。

于 2012-10-03T08:57:10.523 に答える
2

ファイルを閉じないと、プログラムで空きファイル記述子が不足する可能性があります。

男perlfunc:

close
           Closes the file or pipe associated with the filehandle, flushes the IO 
           buffers, and closes the system file descriptor.
于 2012-10-03T06:23:18.230 に答える
1

一部の出力エラーは、ファイルが閉じられるまで遅延する場合があります。したがって、通常はファイルを閉じて戻り値を確認することをお勧めします。のように

# open (my $fd, ">", $fname) somewhere upstream
close $fd 
    or die "Couldn't finish writing to $fname: $!";

それ以外は、プログラムは終了時にグローバルファイルハンドルを閉じ、スコープを離れるたびに字句ハンドルを閉じます。

于 2012-10-03T06:48:58.493 に答える