【问题标题】:File handles not working properly in Perl文件句柄在 Perl 中无法正常工作
【发布时间】:2015-04-21 04:14:47
【问题描述】:

我尝试将两个文件句柄初始化为 NULL,然后在我的程序中使用它。

这是我的代码:

my $fh1 = " ";
my $fh2 = " ";
open($fh1, ">", $fname1);
open($fh2, ">", $fname2);
print $fh1 "HI this is fh1";

执行后,我的文件包含以下内容:

fname1 为空

fname2 包含

Hi this is fh1

错在哪里?

为什么 fname1 是空的,而 fname2 包含一个字符串,即使我没有在 fh2 中插入任何字符串?

【问题讨论】:

  • 你用use strict ; use warnings;试过这个吗?它在公开调用中抛出错误。
  • 当我运行你的代码时,我得到这个:syntax error at fh.pl line 3, near ", >" syntax error at fh.pl line 4, near ", >" Execution of fh.pl aborted due to compilation errors.
  • 它们是文件句柄

标签: perl file filehandler


【解决方案1】:

您已将 $fh1$fh2 设置为相同的值(空格字符,而不是 NULL),因此它们针对 I/O 引用相同的底层 typeglob。

Perl 中的文件句柄是一种特殊的变量类型,称为 glob 或 typeglob。在过去的 Perl 4 中,您总是将 glob 称为字符串,通常称为裸词。裸词STDINSTDOUTSTDERR 是这个简单时代的遗物。

现在,您可以(并且通常应该)使用词法文件句柄,但对 typeglob 的底层引用仍然存在。例如,你可以写

my $fh = 'STDOUT';
print $fh "hello world\n";

这将做与

完全相同的事情
print STDOUT "hello world\n";

现在,如果您将未初始化的标量作为第一个参数传递给open,Perl 将为其分配一个任意类型团。您可能不需要知道它是哪种类型。

但是如果open 的参数已经被初始化,Perl 会使用带有该参数值的typeglob。所以这段 sn-p 代码将创建数据并将数据添加到文件中:

my $fh = "FOO";
open $fh, '>', '/tmp/1';
print FOO "This is going into /tmp/1\n";
close $fh;

现在我们可以看看你的例子。您已将$fh1$fh2 设置为相同的值——一个由空格字符组成的字符串。因此,您对 $fh1open 调用会在名为 " " 的 typeglob 和到 $fname1 的输出流的文件描述符之间创建关联。

当您在$fh2 上调用open 时,您正在重用名为" " 的typeglob,它将使用相同的typeglob ($fh1) 自动关闭另一个文件句柄,就像您说@987654341 @,第二个 open 调用将隐式 close 第一个文件句柄。

现在您在$fh1 上打印,它指的是名为" " 的typeglob,它与文件$fname2 的输出流相关联,这就是输出的位置。

初始化$fh1$fh2 是错误的。让它们未定义:

my ($fh1, $fh2);
open $fh1, ">", ...   # assigns $fh1 to arbitrary typeglob
open $fh2, ">", ...   # assigns $fh2 to different arbitrary typeglob

【讨论】:

  • 你甚至可以写open my $fh1 , '>' , '...' or die "Cannot write: $!\n";
【解决方案2】:

你根本不应该初始化你的文件句柄,否则 Perl 会尝试使用那个值作为文件句柄而不是创建一个新的句柄。在这种情况下,您在文件句柄 ' '(一个空格)上打开了 $fname1,然后在同一个文件句柄上打开了 $fname2,这将关闭 $fname1

与其单独声明文件句柄,不如在open语句中声明,像这样

open my $fh1, '>', $fname1;
open my $fh2, '>', $fname2;

那么出错的可能性就更少了

【讨论】:

    猜你喜欢
    • 2020-08-15
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多