如果我们在 Perl 中不关闭文件会有多严重?

Posted

技术标签:

【中文标题】如果我们在 Perl 中不关闭文件会有多严重?【英文标题】:How severe is it if we do not close a file in Perl? 【发布时间】:2012-09-24 01:10:40 【问题描述】:

如果我在同一个程序中再次访问它会影响程序或文件吗?

【问题讨论】:

无法保证在调用关闭句柄之前将给定的“写入”刷新到输出设备。因此,将一个句柄打开以进行输出,同时将另一个句柄打开到同一文件可能“充满危险”。如果您所做的只是阅读,那么它就不那么重要了。 【参考方案1】:

全局文件句柄将一直存在,直到您的程序退出。这可能很糟糕,但由于您可能不应该使用全局文件句柄,所以这不是问题。

my 的词法文件句柄是 closed,当它们的作用域离开/它们的引用计数降至零时。

如果文件句柄的名称被重用,则先前的文件句柄隐含为closed。以下脚本重用相同的文件句柄来打印任意数量文件的前五行:

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 到读取端。

forking 时,所有未使用的文件句柄都应该关闭,因为它们在分叉时会重复。这意味着在一个进程中关闭管道可能不会发送所需的 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!)
  $SIGPIPE = 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 将不会被触发,并且程序会打印数字 ad infinitum

【讨论】:

【参考方案2】:

某些输出错误可能会延迟到文件关闭。因此,关闭文件检查返回值通常是一个好习惯。如

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

除此之外,程序会在退出时愉快地关闭全局文件句柄,并在它们离开范围时关闭词法句柄。

【讨论】:

【参考方案3】:

如果您不关闭文件,您的程序可能会用完可用的文件描述符。

人perlfunc:

close
           Closes the file or pipe associated with the filehandle, flushes the IO 
           buffers, and closes the system file descriptor.

【讨论】:

以上是关于如果我们在 Perl 中不关闭文件会有多严重?的主要内容,如果未能解决你的问题,请参考以下文章

如果在 perl 中解析大型 xlsx 文件,则处理异常 [关闭]

Perl一行式:处理行号和单词数

使用系统命令将stdout和stderr输出重定向到文件在perl中不起作用[重复]

xampp中的perl文件夹有啥用,为啥它包含在xampp中? [关闭]

perl之文本文件的嵌套循环

当输入文件是.gz文件时,有啥方法可以在perl中使用seek函数[关闭]