標籤: 暫無標籤

在文件I/O中,要從一個文件讀取數據,應用程序首先要調用操作系統函數並傳送文件名,並選一個到該文件的路徑來打開文件。該函數取回一個順序號,即文件句柄(file handle),該文件句柄對於打開的文件是唯一的識別依據。

1 文件句柄 -簡介

  在文件I/O中,要從一個文件讀取數據,應用程序首先要調用操作系統函數並傳送文件名,並選一個到該文件的路徑來打開文件。該函數取回一個順序號,即文件句柄(file handle),該文件句柄對於打開的文件是唯一的識別依據。要從文件中讀取一塊數據,應用程序需要調用函數ReadFile,並將文件句柄在內存中的地址和要拷貝的位元組數傳送給操作系統。當完成任務后,在通過調用系統函數來關閉該文件。

2 文件句柄 -特點

  除了你模仿唯我論者哲學家編寫一個人工智慧程序, 你的程序使用不和外界通訊的方法。在班級例子中的第三和四行, 你將看到"GRADES", 這是引用另一個Perl文件的數據類型, 稱為句柄(filehandle)。一個句柄就是你給一個文件,設備,套接字(socket)或管道的一個名字, 以便幫助你記住你正處理的名字, 並隱藏某些緩存等的複雜性。(在內部, 句柄類似C++語言的流(streams), 或BASIC中的I/O通道)句柄使你從不同的地方輸入和輸出給不同的地方都較容易。使Perl成為好語言的一個原因是它能和多個文件通訊並一次處理他們。對外部對象有好的符號名字是一個好語言的一個組成部分[1]。

  [1]其他使Perl是一個好語言的是: 它是8位的, 是可嵌入的, 你能通過擴展模式在Perl中嵌入其他程序。它是簡明的,網路上容易使用。環境上是清楚的,容易對話。你能以許多不同的方法引用它(就象前面看到的)。總之,語言本身不是如此嚴格的結構,以至於你不能使它超出你的問題。又回到TMTOWTDI。

  你創建一個句柄,並通過open函數把它和一個文件聯結。open有兩個參數: 句柄和你想與它聯結的一個文件名。Perl也給出一些預定義(和預打開的)句柄。stdin是你程序的正常輸入通道, 而STDOUT是你程序的正常輸出的通道。STDERR是一個附加的輸出通道, 以便當把輸入轉為輸出時, 程序能給出一些說明[2]。

  [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把這個句柄和另一文件聯結&#91;3&#93;。

  &#91;3&#93;打開一個已打開的句柄是隱式地關閉第一個文件, 使它對文件句柄不可取,並打開一個不同的文件。你必須小心這是你真正想做的。有時,偶然碰巧,比如,當你open($handle,$file)時, $handle正好包含空串(null)。確認設置$handle為某個單一個量, 否則你將對空句柄打開一個新的文件。

  一旦你已為輸入打開一個句柄(或你使用STDIN), 你就能使用"行讀操作"<>, 讀一行。這個也以鑽石操作聞名,因為它的形狀。這個鑽石操作包含你想讀的句柄(<SESAME>)&#91;4&#93;。使用STDID句柄讀用戶提供的答案, 如下:

  &#91;4&#93;空鑽石操作<>, 將從命令行指定的所有文件讀, 如果沒有指定, 從STDIN讀。(這是許多UNIX"過濾"程序的標準行為)

  print STDOUT "Enter a number: "; #請求輸入一個數

  $number = <STDIO>; #輸入一個數

  print STDOUT "The number is $number"; #輸出這個數

  你明白我們給你的例子嗎?在print語句中STDOUT做什麼?這就是你使用一個輸出句柄的方法之一。一個句柄可以作為print語句的第一個參數, 如果存在, 告訴往哪兒輸出。在例子中,句柄是冗餘的,因為輸出已經是STDOUT。對於輸入的預設是STDIN, 對於輸出的預設是STDOUT。(在班級例子的18行, 我們為避免使你混淆, 我們省略了。)

  我們也有一件事使你不明白。如果你試上面的例子,你可以注意到你得到一個特別的空行。因為讀時沒有自動地從你的輸入行中刪除換行符(newline)(例如, 你輸入"9")。對於這些情況,當你想刪除換行符時,Perl提供chop和chomp函數。chop將不加區別地刪除(並返回)傳給它的最後一個字元, 而chomp只刪除記錄標識的末尾(一般地是""), 並返回這樣刪除的字元數。你將經常看到這樣輸入一行:

  chop($number = <STDIN>); #輸入一個數並刪除換行符

  意思是:

  $number = <STDIN>; #輸入一個數

  chop($number); #刪除換行符

  mov

  int

  mov

  int

  endp

  ends

  end ah,9

  21h

  ah,4ch

  21h

  main

  ;結束進程

  這是一個不尋常的程序,它的特殊性就在於使用了"不尋常"的文件句柄。還記得前面我們討論文件句柄時所遺留的那個問題嗎?我們打開的第一個文件的句柄號是05H而不是00H,之所以這樣是因為句柄號00H-04H已經被佔用了。而且更為特殊的是這五個句柄不是賦予五個文件的,而是賦予五種硬體設備。這聽上去好象越來越亂了,文件和硬體設備竟然又出現了某種聯繫,實在讓人搞不明白。我想若要弄清楚這個問題,我們還是要從一些實際現象出發。

  學過C語言的朋友一定接觸過fprintf函數的這樣一個用法:

  fprintf(STDERR,"DANGER!!!......Found a VIRUS......");

  本來,在STDERR這個位置上應該是指向一個文件的指針,這個指針的含義和我們現在討論的文件句柄是一樣的(我想也許彙編語言中的文件句柄就是C語言中文件指針的實質,我沒有查過權威資料,這個看法是否正確還有待檢驗)。現在我們在這個位置上放了一個稱為STDERR的常量,而且我們知道這樣使用fprintf函數可以使引號中的文字出現在顯示器上而不是某個文件中,而顯示器又恰好是一個硬體設備。由此看來,文件、文件指針和硬體設備確實應該存在某種聯繫,這種聯繫並非在彙編語言程序設計中有體現,在C這樣的高級語言中已經體現出來了。那麼STDERR又是個什麼東西呢?

  這個常量出現在名為STDIO.H的一個包含文件中,在C語言中它被稱為"標準錯誤輸出設備(STanDard ERRor output device)"C語言中還有兩個比較常用的常量,分別為STDIN和STDOUT,即標準輸入和標準輸出設備。這三種設備通常都與鍵盤和顯示器有關,使用fprintf函數從STDIN讀入數據時相當於等待鍵盤輸入;而向STDOUT或STDERR輸出的內容都會出現在顯示器上。這就有點兒象我們剛剛給出的那個彙編程序,在那個彙編程序中我們在輸出數據時使用了一個特殊的句柄,結果導致了所有的文字都出現於顯示器上而沒有寫入什麼文件中。

  看來我們所使用的那個特殊句柄代表的是顯示器而不是文件。我們所使用的DOS系統還有這樣一個有趣的功能不知道你是否使用過,那就是"重定向"功能。如果在DOS狀態下按下面這樣的格式使用DIR命令,大家就會發現文件和設備確實具有某種不尋常的聯繫:

  C:\DOS\>DIR>FILE.LST

  本來會出現在顯示器上的一行行文件名都跑到一個名叫"FILE.LST"的文件中去了。由此我們設想這樣一個結論:我們通過調用DOS的文件句柄功能不僅可以操作文件,同樣可以操作一些硬體設備。

  這個結論是完全正確的,事實上文件與設備本身就具有一些相似的特點:文件可以讀入或寫出,而硬體設備同樣可以"讀入"(鍵盤)和"寫出"(顯示器、印表機)。既然它們具有這樣相同的特性,當然可以使用同樣的形式來操作,這就是DOS為我們提供了那五個特殊句柄的原因。我們下面就來詳細談談這五個特殊的句柄:

  表8-3列出了這五個句柄所代表的硬體設備,其中0、1、2三個句柄是我們最常用的。這五種設備在DOS啟動之後就已經"打開",所以我們可以直接使用這五個句柄而不必再編製代碼將其打開。有關這五個特殊句柄還有一些更值得深思的地方,比如,我們能否使用3FH功能從句柄2所表示的設備中讀入信息?能否使用40H功能向句柄3所表示的設備輸出信息?我們能否用3EH功能關閉某個句柄所表示的設備?分析這樣的問題也非難事,編個程序試一試即可。

  句 柄 設備名稱 邏輯設備名 預設設備

  00 標準輸入設備 CON 鍵盤

  01 標準輸出設備 CON 顯示器

  02 標準錯誤設備 CON 顯示器

  03 標準輔助設備 AUX 串列口

  04 標準列表設備 PRN 印表機

  至此有關文件操作的幾個重要功能--建立、打開、讀寫、關閉--我們都已經討論,不是很全面,沒有深入的地方還要大家自行研究。我們下面的任務就是來討論文件句柄的一些輔助功能,以此做為這一內容的結束。

  句柄是操作系統在生成對象時分配給對象的唯一標識。 通過句柄可以獲取操作系統提供的服務。句柄不同於指針,如果你得到一個對象的指針,那你就可以在此對象上為所欲為了!於是系統不給你指針,而給用戶一個加了限制的,用於跟蹤對象的指針的標識——句柄!系統使用句柄向外提供服務就相對安全了! 操作系統是通過API提供服務的,對於用戶來說,句柄等同於對象指針,但實際上句柄和指針根本不是一回事!

上一篇[分揀]    下一篇 [運算符優先順序]

相關評論

同義詞:暫無同義詞