3

我尝试将两个文件句柄初始化为 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 中插入任何字符串?

4

2 回答 2

3

您已将$fh1and设置$fh2为相同的值(空格字符,而不是 NULL),因此它们为 I/O 引用相同的基础类型团。

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

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

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

这将做同样的事情

print STDOUT "hello world\n";

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

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

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

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

当您调用openon 时$fh2,您正在重用名为 的 typeglob " ",它将使用相同的 typeglob ( $fh1) 自动关闭另一个文件句柄,就像您说的一样open FOO, ">/tmp/1"; open FOO, ">/tmp/2",第二次open调用将隐含close第一个文件句柄。

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

初始化$fh1和是一个错误$fh2。只是让它们未定义:

my ($fh1, $fh2);
open $fh1, ">", ...   # assigns $fh1 to arbitrary typeglob
open $fh2, ">", ...   # assigns $fh2 to different arbitrary typeglob
于 2015-04-21T05:49:31.003 回答
1

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

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

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

那么可能出错的地方就更少了

于 2015-04-21T09:12:46.930 回答