目前還沒介紹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"; }