【问题标题】:cleaner method to open and close filehandles dynamically?动态打开和关闭文件句柄的更清洁方法?
【发布时间】:2018-05-17 05:12:08
【问题描述】:

我有一个条目数组,将在一个大文件中搜索,然后将每个条目写入其自己的输出文件。数组根据某些条件而变化,因此必须是动态的。

这是我的示例array

use strict;
use warnings;

my @array = ("ABC",
             "DEF",
             "GHI",
             "JKL",
             "MNO",
             "PQR"
             );

所以我创建了一个循环来打开为每个条目创建一个文件句柄。运行我的命令,然后再次循环关闭文件句柄。

foreach my $handle(@array) {
        my $output = "OUTPUT_$handle.txt";
           open ($handle, '>', $output) or die "unable to open file $!";
}

#... write to files and do some other fancy stuff ...

foreach $handle(@array) {
           close $handle;
    }

这将创建:OUTPUT_ABC.txtOUTPUT_DEF.txt.. 等等。

所以我的问题:对我来说,不得不循环打开每个句柄并循环关闭每个句柄似乎很尴尬,有没有更优雅的方法来动态打开和关闭文件句柄?

【问题讨论】:

  • 使用词法文件句柄,它们在超出范围时关闭。

标签: perl


【解决方案1】:

我不明白您的担忧,但您可以使用语句修饰符使其更简洁。此外,使用autodie pragma 无需检查每个操作的状态

use autodie;

open $_, '>', "OUTPUT_$_.txt" for @array;

...

close for @array;

请注意,如果您将使用 @array 中文件句柄的代码包装在一个块 { ... } 中,那么当它们超出范围时,它们将被隐式关闭。您只需要确保声明 my @array(顺便说一下,这是一个糟糕的标识符)在块内

【讨论】:

  • 这不是什么大问题,可能只是我的强迫症。这就是我所说的更优雅的意思。谢谢
  • 那些是词法文件句柄还是旧式句柄?因为@array 是一个字符串数组,而不是文件句柄,所以我的直觉是它们超出范围时不会关闭。
  • @el.pescado:它们使用词法数组元素,因此它们是词法句柄。除了构建文件名字符串之外,数组的原始内容无关紧要。对open 的调用会用新的文件句柄引用覆盖每个数组元素。
  • @Borodin 你确定吗? print Dumper \@array; 另有说明。 system("ls -l /proc/$$/fd"); 表示文件仍处于打开状态。
  • 好的,找到了。 "如果 FILEHANDLE 是一个 undefined 标量变量(或数组或散列元素),则自动激活新的文件句柄,这意味着该变量被分配了对新分配的匿名文件句柄的引用。否则,如果 FILEHANDLE是一个表达式,它的值是真正的文件句柄。(这被认为是一个符号引用,所以使用严格的“refs”不应该生效。)”(perldoc open) 因此,将词法值传递给 open 是不够的 - 它必须是未定义的。此代码打开ABCDEF 等旧式文件句柄。
【解决方案2】:

你可以使用lexical filehandles:

use strict;
use warnings;

my @array = qw/ABC DEF/;

{
    my %fh = map { open my $fh, ">", "OUTPUT_$_.txt"; $_ => $fh } @array;
    print $fh{ABC} "Something...";
}
# Here your filehandles in %fh will be closed already.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多