问题
How severe is it if we do not close a file in Perl? Will it affect the program or file if I access it again in the same program?
回答1:
Global filehandles will stay around until your program exits. This may be bad, but as you probably shouldn't be using global filehandles anyway, this is a non-issue.
Lexical filehandles with my
are close
d when their scope is left / their reference count drops to zero.
If the name of a filehandle is re-used, the previous filehandle is close
d implicitely. The following script reuses the same filehandle to print the first five lines of any number of files:
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
}
When working with files, explicitely closing the FH is unimportant. However, it is critical when doing IPC. Closing a writing end to a pipe indicates EOF to the reading end.
When fork
ing, all unused filehandles should be closed, because they are duplicated while forking. This means that closing a pipe in one process might not be sending the desired EOF, because the same pipe is still open in a related process.
Here is a program that demonstrates the importance of close
in 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";
}
The output of this program is the numbers 1 to 5. Then the child closes its end to the pipe, triggering SIGPIPE
in the parent. While the parent dies, the child lingers around for 5 seconds until it dies too.
This works because the parent closed its reading end to the pipe. If close $out
is removed from the parent, SIGPIPE
would not be triggerd, and the program print numbers ad infinitum.
回答2:
Your program may run out of free file descriptors if you do not close the files.
man perlfunc:
close
Closes the file or pipe associated with the filehandle, flushes the IO
buffers, and closes the system file descriptor.
回答3:
Some output errors may be delayed until file is closed. So it is generally a good practice to close files and check the return value. As in
# open (my $fd, ">", $fname) somewhere upstream
close $fd
or die "Couldn't finish writing to $fname: $!";
Other than that, the program will happily close global filehandles on exit, and lexical ones whenever they leave scope.
来源:https://stackoverflow.com/questions/12702869/how-severe-is-it-if-we-do-not-close-a-file-in-perl