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";
}
相關文章
相關標籤/搜索