在檔案I/O中,要從一個檔案讀取資料,應用程式首先要叫用作業系統函數並傳送檔案名稱,並選一個到該檔案的路徑來開啟檔案。該函數取回一個順序號,即Perl檔案控制代碼(filehandle),該Perl檔案控制代碼對於開啟的檔案是唯一的識別依據。要從檔案中讀取一塊資料,應用程式需要調用函數ReadFile,並將Perl檔案控制代碼在記憶體中的地址和要拷貝的位元組數傳送給作業系統。當完成任務後,在通過調用系統函數來關閉該檔案。
除了你模仿唯我論者哲學家編寫一個人工智慧程式,你的程式使用不和外界通訊的方法。在班級例子中的第三和四行,你將看到"GRADES",這是引用另一個Perl檔案的資料類型,稱為據柄(filehandle)。一個控制代碼就是你給一個檔案,裝置,管套(socket)或管道的一個名字,以便協助你記住你正處理的名字,並隱藏某些緩衝等的複雜性。(在內部,控制代碼類似C++語言的流(streams),或BASIC中的I/O通道)控制代碼使你從不同的地方輸入和輸出給不同的地方都較容易。使Perl成為好語言的一個原因是它能和多個檔案通訊並一次處理他們。對外部對象有好的符號名字是一個好語言的一個組成部分[1]。
其他使Perl是一個好語言的是:它是8位的,是可嵌入的,你能通過擴充模式在Perl中嵌入其他程式。它是簡明的,網路上容易使用。環境上是清楚的,容易對話。你能以許多不同的方法引用它(就象前面看到的)。總之,語言本身不是如此嚴格的結構,以至於你不能使它超出你的問題。又回到TMTOWTDI。
你建立一個控制代碼,並通過open函數把它和一個檔案連接。open有兩個參數:控制代碼和你想與它連接的一個檔案名稱。Perl也給出一些預定義(和預開啟的)控制代碼。STDIN是你程式的正常輸入通道,而STDOUT是你程式的正常輸出的通道。STDERR是一個附加的輸出通道,以便當把輸入轉為輸出時,程式能給出一些說明[2]。
一般地,這些控制代碼和你的終端連接,所以你能輸入你的程式並能看到,但他們也可以和檔案連接。Perl能給你這些預定義控制代碼,因為你的作業系統已提供這些。在UNIX下,進程從他的父進程(一般是一個shell)繼承標準輸入,輸出和錯誤。一個shell的責任之一是建立這些I/O流,以便子進程不必考慮這些)。
既然你能為各種目的(輸入,輸出,管道)使用open函數建立控制代碼,你就必須能指明你要做什麼。就象在UNIX命令列一樣,你給檔案名稱簡單地加些字元。
複製代碼 代碼如下:open(SESAME,"filename");#從已存在的檔案讀
open(SESAME,"<filename");#顯式地,同上面
open(SESAME,">filename");#建立一個檔案並對它寫
open(SESAME,">>filename");#對已有的檔案接著寫
open(SESAME,"|output-pipe-command");#建立一個輸出過濾
open(SESAME,"input-pipe-command|");#建立一個輸入過濾
就象你看到的,你可以任意選名字。一旦開啟控制代碼SESAME,它就能被用於存取檔案或管道,直到它被顯式地關閉(用close(SESAME)),或對同一控制代碼的一系列open把這個控制代碼和另一檔案連接[3]。
開啟一個已開啟的控制代碼是隱式地關閉第一個檔案,使它對Perl檔案控制代碼不可取,並開啟一個不同的檔案。你必須小心這是你真正想做的。有時,偶然碰巧,比如,當你open($handle,$file)時,$handle正好包含空串(null)。確認設定$handle為某個單一個量,否則你將對空控制代碼開啟一個新的檔案。
一旦你已為輸入開啟一個控制代碼(或你使用STDIN),你就能使用"行讀操作"<>,讀一行。這個也以鑽石操作聞名,因為它的形狀。這個鑽石操作包含你想讀的控制代碼()[4]。使用STDID控制代碼讀使用者提供的答案,如下:
空鑽石操作<>,將從命令列指定的所有檔案讀,如果沒有指定,從STDIN讀。(這是許多UNIX"過濾"程式的標準行為)
複製代碼 代碼如下:printSTDOUT"Enteranumber:";#請求輸入一個數
$number=<STDIO>;#輸入一個數
printSTDOUT"Thenumberis$number";#輸出這個數
你明白我們給你的例子嗎?在print語句中STDOUT做什麼?這就是你使用一個輸出控制代碼的方法之一。一個控制代碼可以作為print語句的第一個參數,如果存在,告訴往哪兒輸出。在例子中,控制代碼是冗餘的,因為輸出已經是STDOUT。對於輸入的預設是STDIN,對於輸出的預設是STDOUT。(在班級例子的18行,我們為避免使你混淆,我們省略了。)
我們也有一件事使你不明白。如果你試上面的例子,你可以注意到你得到一個特別的空行。因為讀時沒有自動地從你的輸入行中刪除分行符號(newline)(例如,你輸入"9")。對於這些情況,當你想刪除分行符號時,Perl提供chop和chomp函數。chop將不加區別地刪除(並返回)傳給它的最後一個字元,而chomp只刪除記錄標識的末尾(一般地是""),並返回這樣刪除的字元數。