文件

2018-02-24 16:03 更新

利用?open?和?<>?操作符更易讀取文件

使用 Perl 打開并讀取文件很簡(jiǎn)單。下面的示例代碼演示如何打開文件, 一行一行地讀取,檢查匹配正則表達(dá)式的文本,以及輸出匹配的行。

open( my $fh, '<', $filename ) or die "Can't open $filename: $!";
while ( my $line = <$fh> ) {
    if ( $line =~ /wanted text/ ) {
        print $line;
    }
}
close $fh;

總是檢查?open?的返回碼是否為真。如果為假,其結(jié)果在?$!?中。

利用?chomp?移除結(jié)尾的換行符

從文件讀取行時(shí)會(huì)包含結(jié)尾的換行符。假如你有一個(gè)文本文件,其第一行是:

Aaron

Aaron?實(shí)際上是 6 個(gè)字符Aaron\n。此代碼將失?。?/p>

my $line = <$fh>;
if ( $line eq 'Aaron' ) {
    # won't reach here, because it's really "Aaron\n";
}

要移除?\n?及結(jié)尾的其他任意空白,調(diào)用?chomp。

my $line = <$fh>;
chomp $line;

現(xiàn)在?$line?為 5 個(gè)字符長(zhǎng)。

利用?$/?更改行分隔符

可以更改輸入記錄分隔符?$/,其默認(rèn)設(shè)置為?\n。

設(shè)置?$/?一次讀取一段。設(shè)置?$/?為?undef?將一次讀取整個(gè)文件。 參閱?perlvar?了解細(xì)節(jié)。

一次讀取整個(gè)文件

你將注意到新手在讀取文件時(shí)會(huì)使用下述兩種方法之一:

open (FILE,$filename) || die "Cannot open '$filename': $!";
undef $/;
my $file_as_string = <FILE>;

或:

open (FILE,$filename) || die "Cannot open '$filename': $!";
my $file_as_string = join '', <FILE>;

選擇兩種中的前者。第二種讀取所有行到數(shù)組,然后組合成一個(gè)大字符串。 第一種僅讀取到字符串,不會(huì)間接創(chuàng)建行列表。

然而最佳的方式是像這樣:

my $file_as_string = do {
    open( my $fh, $filename ) or die "Can't open $filename: $!";
    local $/ = undef;
    <$fh>;
};

do?塊返回塊中最后求解的值。此方法將?$/?設(shè)置為局部作用域,所以 超出塊范圍會(huì)設(shè)置為默認(rèn)值。如果沒有局部化?$/,那么它將保留設(shè)置的 值,其他代碼段可能并不期望它被設(shè)置為?undef。

下面是另一種方法:

use File::Slurp qw( read_file );
my $file_as_string = read_file( $filename );

File::Slurp?是一次性讀取和寫入的有用模塊,它將在背后做魔術(shù)般的快速 處理。

利用?glob()?獲取文件列表

使用標(biāo)準(zhǔn)的 Shell 展開模式來獲取文件列表。

my @files = glob( "*" );

將它們傳遞給?grep?來做快速過濾。例如,要獲取文件而非目錄:

my @files = grep { -f } glob( "*" );

使用?unlink?移除文件

Perl 內(nèi)置函數(shù)?delete?用來刪除哈希的元素,而非文件系統(tǒng)中的文件。

my %stats;

$stats{filename} = 'foo.txt';

unlink $stats{filename}; # RIGHT: Removes "foo.txt" from the filesystem

delete $stats{filename}; # WRONG: Removes the "filename" element from %stats

術(shù)語(yǔ)?unlink?來自于 Unix 從目錄節(jié)點(diǎn)移除文件鏈接的想法。

在 Windows 下使用 Unix 風(fēng)格的目錄

即使 Unix 使用?/usr/local/bin,而 Windows 使用?C:\foo\bar\bat?這樣的路徑, 你仍然能夠在文件名中使用斜杠。

my $filename = 'C:/foo/bar/bat';
open( my $fh, '<', $filename ) or die "Can't open $filename: $!";

在這種情況下,Perl 在打開文件前魔術(shù)化地將?C:/foo/bar/bat?更改為C:\foo\bar\bat。 這也會(huì)防止文件名包含未引起的反斜杠所帶來的問題。

my $filename = "C:\tmp";

$filename?包含 5 個(gè)字符:C、:、tab 字符、m、及 p。實(shí)際上,它應(yīng)該寫成:

my $filename = 'C:\tmp';
my $filename = "C:\\tmp";

或者你讓 Perl 來照料它:

my $filename = 'C:/tmp';
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)