How severe is it if we do not close a file in Perl?

与世无争的帅哥 提交于 2019-12-09 17:58:25

问题


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 closed when their scope is left / their reference count drops to zero.

If the name of a filehandle is re-used, the previous filehandle is closed 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 forking, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!