记住你可以这样做:
$ perl -le '$fh = "STDOUT";打印 $fh "你好"'
你好
这是一个普通的字符串,但仍可用作文件句柄。
查看source of IO::Handle,它的opened 是fileno 的薄包装,它有一个方便的属性:
返回文件句柄的文件描述符,如果文件句柄未打开,则返回 undefined。
但有一个警告:
通过 open 的新功能连接到内存对象的文件句柄可能会返回 undefined,即使它们是打开的。
然后看起来像这样的测试
$@ = "";
my $fd = eval { fileno $maybefh };
my $valid = !$@ && defined $fd;
会做你想做的。
下面的代码检查代表
- 内存中的对象
- 命名文件句柄
- 球体
- 全局引用
- 全局名称
- 标准输入
-
FileHandle 实例
-
IO::File 实例
- 管道
- 先进先出
- 套接字
自己运行:
#! /usr/bin/perl
use warnings;
use strict;
use Fatal qw/ open /;
use FileHandle;
use IO::File;
use IO::Socket::INET;
my $SLEEP = 5;
my $FIFO = "/tmp/myfifo";
unlink $FIFO;
my $pid = fork;
die "$0: fork" unless defined $pid;
if ($pid == 0) {
system("mknod", $FIFO, "p") == 0 or die "$0: mknod failed";
open my $fh, ">", $FIFO;
sleep $SLEEP;
exit 0;
}
else {
sleep 1 while !-e $FIFO;
}
my @ignored = (\*FH1,\*FH2);
my @handles = (
[0, "1", 1],
[0, "hashref", {}],
[0, "arrayref", []],
[0, "globref", \*INC],
[1, "in-memory", do {{ my $buf; open my $fh, "<", \$buf; $fh }}],
[1, "FH1 glob", do {{ open FH1, "<", "/dev/null"; *FH1 }}],
[1, "FH2 globref", do {{ open FH2, "<", "/dev/null"; \*FH2 }}],
[1, "FH3 string", do {{ open FH3, "<", "/dev/null"; "FH3" }}],
[1, "STDIN glob", \*STDIN],
[1, "plain read", do {{ open my $fh, "<", "/dev/null"; $fh }}],
[1, "plain write", do {{ open my $fh, ">", "/dev/null"; $fh }}],
[1, "FH read", FileHandle->new("< /dev/null")],
[1, "FH write", FileHandle->new("> /dev/null")],
[1, "I::F read", IO::File->new("< /dev/null")],
[1, "I::F write", IO::File->new("> /dev/null")],
[1, "pipe read", do {{ open my $fh, "sleep $SLEEP |"; $fh }}],
[1, "pipe write", do {{ open my $fh, "| sleep $SLEEP"; $fh }}],
[1, "FIFO read", do {{ open my $fh, "<", $FIFO; $fh }}],
[1, "socket", IO::Socket::INET->new(PeerAddr => "localhost:80")],
);
sub valid {
local $@;
my $fd = eval { fileno $_[0] };
!$@ && defined $fd;
}
for (@handles) {
my($expect,$desc,$fh) = @$_;
print "$desc: ";
my $valid = valid $fh;
if (!$expect) {
print $valid ? "FAIL\n" : "PASS\n";
next;
}
if ($valid) {
close $fh;
$valid = valid $fh;
print $valid ? "FAIL\n" : "PASS\n";
}
else {
print "FAIL\n";
}
}
print "Waiting for sleeps to finish...\n";
所有都在 Ubuntu 9.10 机器上通过,因此至少在该平台上,有关内存对象的警告似乎不是问题。
1:通过
哈希引用:通过
数组引用:通过
全局引用:通过
内存中:通过
FH1 全局:通过
FH2 全局引用:通过
FH3 字符串:PASS
标准输入:通过
普通阅读:通过
纯写:通过
FH 读取:通过
FH 写:通过
I::F 读取:通过
I::F 写:通过
管道读取:通过
管道写入:通过
FIFO读取:通过
套接字:通过