您好,登錄后才能下訂單哦!
標準輸入輸出
STDIN可以用于接收鍵盤輸入或是文件輸入。在標量上下文中執行該操作時,會返回輸入中的下一行。
while <STDIN> { chomp; print "I saw $_"; } foreach <STDIN> { chomp; print; }
看起來上例中的“while”循環和“foreach”的行為完全一樣,其實是有些差別的——在while循環里,Per會讀取一行輸入,把它存入某個變量并且執行循環的主體,接下來它會回去尋找其他輸入行;foreach循環中,行輸入操作符會在列表上下文中執行(因為foreach需要逐項處理列表內容),因此Perl會將全部內容讀入內存,然后才開始執行循環。當需要處理的輸入數據長度很大時,比如處理400M大小的Web服務器日志文件,foreach的效率會比while低很多。因此最好的做法是盡量使用while循環,讓它每次處理一行。
鉆石操作符的輸入<>
鉆石操作符提供類似 標準Unix工具程序的參數輸入方式,例如對于如下Perl程序“my_program”:
while <> { chomp; print; }
如果執行命令“./my_program fred barney betty”,它應該會處理文件fred,接著是barney,最后是betty。(鉆石操作符怎么會知道檢查命令行參數呢?其實它的參數是來自@ARGV數組)
如果執行命令是沒有指定調用參數,程序會從標準輸入流采集數據。
當然還有個例外,如果參數中包含連字符“-”,則Perl代碼處理到連字符時,會臨時改從標準輸入讀取數據。
使用print/printf/say輸出到標準輸出
Print操作符會讀取后續列表中的所有元素,并把每一項一次送到標準輸出。
print <>; #相當于Unix下的cat命令 print sort <>; #相當于Unix下的sort命令
如果對print的輸出格式不夠滿意,還可以使用printf來產生格式化過的輸出結果。
printf "Hello, %s; your password expires in %d days!\n", $user, $days_to_die;
當然Perl一如既往地提供了更方便的格式"%g" (你可以把"g"當成"General"數字轉換)。
一般來說,我們編寫printf的格式化字符串時已經確定了替換參數的個數和類型,不過萬事沒有絕對,下面的例子就是用程序在運行時動態產生格式字符串。
my @items = qw( wilma dino pebbles ); my $format = "The items are: \n" . ("%10s\n" x @items); printf $format, @items;
另外,有個叫Perl Power Tools (PPT)的項目目標就是用perl重寫所有經典Unix工具程序,但是在重寫shell的時候陷入了難題。PPT項目一度非常有用,因為它使所有便準的工具程序可以運行在非Unix機器上。
Say函數的功能和print的差不多,但在打印每行內容時都會自動加上換行符。所以下面幾種寫法的輸出結果都一樣:
use 5.010 print "Hello!\n"; print "Hello!" . "\n"; say "Hello!";
文件句柄
一般使用全大寫字母來命名文件句柄,但是有6個個數文件句柄是Perl保留的——STDIN、STDOUT、STDERR、DATA、ARGV以及ARGVOUT。
open CONFIG, 'dino'; #打開一個文件 open CONFIG, '<dino' #只讀方式打開一個文件 open REDROCK, '>fred' #創建一個新的文件,如果已經存在,則清除原有內容并以新內容代替 open LOG, '>>logfile' #追加方式打開一個文件,如果文件不存在,則創建一個新文件
5.6版的Perl里,加入了open的三個參數的寫法:
open CONFIG, '<', 'dono'; open BEDROCK, '>', $file_name; open CONFG, '<:encoding(UTF-8)', $file_name; #使用UTF-8編碼打開文件,這種書寫方式會確認編碼是否正確 open BEDROCK, '>:utf8', &logfile_name(); #這種簡寫的方式不會考慮輸入輸出的數據是否真的是合法的UTF-8字符串
我們可以通過下面的這條命令打印出說有perl能理解的字符編碼清單:
% perl -MEncode -le "print for Encode->encodings(':all')"
除了字符編碼之外,數據輸入或輸出過程中還可以做其他轉換操作。比如DOS風格和Unix風格的換行符:
open BEDROCK, '>:crlf', $file_name; #按照DOS換行符風格寫入文件 open BEDROCK, '<:crlf', $file_name; #讀取DOS風格的文件
關閉文件句柄
close BEDROCK;
出錯處理
當Perl遇到致命錯誤時,你的程序應該立刻中止運行,并發出錯誤信息告知原因。這樣的功能可以用die函數來實現。
if ( ! open LOG, '>>', 'logfile' ) { die "Cannot create logfile: $!"; #die函數會終止程序的運行并打印出錯信息 }
"$!"代表可讀的系統錯誤信息。一般來說,當系統拒絕我們的請求時,"$!"會給出一個解釋,類似于C語言中調用perror取得的字符串。
如果Perl遇到的錯誤是非致命的,可以使用warn函數送出警告信息。warn函數的功能就是產生類似于Perl的內置警告信息的信息(比如啟用警告信息時,使用某個undef變量卻將它當成已有的值來參與計算,就會觸發警告信息)。
自動檢測致命錯誤
從Perl 5.10開始,為人稱道的autodie編譯指令已經成為標準庫的一部分。
use autodie;
這條編譯指令是靠判別具體操作的類型來工作的。如果Perl內置函數調用了操作系統接口的話,那么中途出現的錯誤并不是編程人員所能控制的,所以一旦發現系統調用出錯,autodie便會自動幫你調用die。
使用文件句柄
以寫入或添加方式打開文件后,可以直接使用print或printf將字符串輸出到文件中:
print LOG "Captain's log, stardate 3.14159"; printf STDERR "%d percent complete.\n", $done/$total * 100;
如果print/printf的參數列表沒有提供文件句柄,則字符串默認被輸出到STDOUT。不過可以使用select操作符改變默認的文件句柄,另外還有一個很奇特的變量"$|",當它的值被設為1,就會使當前的默認句柄在每次輸出操作后立刻刷新緩沖區。所以,如果要讓輸出的內容立即顯示(比如在讀取監視某個耗時程序的實時日志時),應該這么做:
select LOG; # 將默認輸出設定為LOG文件句柄 $|= 1; # 不要將LOG的內容保留在緩沖區 select STDOUT; print LOG "This gets written to the LOG at once!\n";
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。