Perl文件句柄引用

目前还没介绍Perl的面向对象,因此这节内容除了几个注意点,没什么可讲的。数组

之前常常使用大写字母的句柄方式(即所谓的裸字文件句柄,bareword filehandle),如今能够考虑转向使用变量文件句柄的形式,由于只有使用变量句柄的方式,才能建立文件句柄引用。数据结构

open DATA,">>","/tmp/a.log" or die "can't open file: $!";
open my $data_fh ,">>","/tmp/a.log" or die "can't open file: $!";
open my $fh, '<', 'castaways.log' or die "Could not open castaways.log: $!";

裸字文件句柄和变量文件句柄用法是彻底一致的,能用裸字文件句柄的地方均可以替换为变量文件句柄:less

while( <DATA> ) { ... }
while( <$log_fh> ) { ... }

无论使用裸字仍是变量文件句柄的方式,在退出文件句柄所在做用域的时候,都会自动关闭文件句柄,无需手动close。函数

只是须要注意的是,使用变量文件句柄的方式,在say/print输出的时候,指定文件句柄时须要使用大括号包围,以避免产生歧义:ui

print {$data_fh} "your output content";

若是想要让某个函数指定输出的文件句柄,也简单,只需将文件句柄做为一个参数便可:this

log_message( $log_fh, 'My name is Mr. Ed' );
sub log_message {
    my $fh = shift;
    print $fh @_, "\n";
}

字符串句柄

除了能够将句柄关联到文件(open)、管道、套接字、目录(opendir),还能够将句柄关联到字符串。也就是将一个变量做为文件句柄的关联对象,从这个变量读或从这个变量写。code

例如:对象

open my $string_fh, '>>', \my $string;
open my $string_fh, '<', \$multiline_string;

上面第一句声明了一个词法变量$string(初始化为Undef),同时建立了一个文件句柄$string_fh,这个文件句柄的输出对象是词法变量$string指向的数据对象。第二句则是从字符串$multiline_string中读取数据。blog

如今能够向这个文件句柄中输出一些数据,它们会存储到$string中:作用域

#!/usr/bin/perl

open my $string_fh, ">>",\my $string or die "...$!";

print {$string_fh} "first line\n";
print {$string_fh} "second line";

print $string,"\n";   # 输出两行:first line和second line

若是想将流向标准输出STDOUT默认设备(终端屏幕)的内容改输出到字符串中,须要当心一些,由于STDOUT毕竟是标准输出,程序的不少部分可能都须要使用它。因此,尽可能在一小片范围内修改标准输出的目标。例如,使用大括号包围,并将STDOUT进行local化(裸字文件句柄只能用local修饰):

print "1. This goes to the real standard output\n";
my $string;
{
    local *STDOUT;
    open STDOUT, '>', \ $string;
    print "2. This goes to the string\n";
    $some_obj->noisy_method();   # this STDOUT goes to $string too
}
print "3. This goes to the real standard output\n";

文件句柄容器

说法有点高大上,其实就是将文件句柄存储到数据结构中(例如hash、数组),作一个装文件句柄的容器。

例如,有一个文件a.txt,内容以下。如今想将每一行第二列、第三列存储到以第一列命名的变量中。

malongshuai big 1250
malongshuai small 910
gaoxiaofang big 1250
gaoxiaofang small 450
tuner middle 1218
wugui middle 199

以下:

use v5.10; # for state
while( <> ) {
    state $fhs;   # 定义一个hash引用变量
    my( $source, $destination, $bytes ) = split;
    unless( $fhs->{$source} ) {  # 当hash键(第一列)不存在时,建立字符串句柄
        open my $fh, '>>', $source or die '...';
        $fhs->{$source} = $fh;
    }
    say { $fhs->{$source} } "$destination $bytes";
}
相关文章
相关标签/搜索