檔案句柄

檔案句柄

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

基本介紹

  • 中文名:檔案句柄
  • 外文名:file handle
  • 重要性:對於打開的檔案是唯一的識別依據
  • 特點:方便對檔案的搜尋與隱藏
特點
一個句柄就是你給一個檔案,設備,套接字(socket)或管道的一個名字, 以便幫助你記住你正處理的名字, 並隱藏某些快取等的複雜性。(在內部, 句柄類似C++語言的流(streams), 或BASIC中的I/O通道)句柄使你從不同的地方輸入和輸出給不同的地方都較容易。使Perl成為好語言的一個原因是它能和多個檔案通訊並一次處理他們。對外部對象友好的符號名字是一個好語言的一個組成部分[1]。
[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]。
[3]打開一個已打開的句柄是隱式地關閉第一個檔案, 使它對檔案句柄不可取,並打開一個不同的檔案。你必須小心這是你真正想做的。有時,偶然碰巧,比如,當你open($handle,$file)時, $handle正好包含空串(null)。確認設定$handle為某個單一個量, 否則你將對空句柄打開一個新的檔案。
一旦你已為輸入打開一個句柄(或你使用STDIN), 你就能使用"行讀操作"<>, 讀一行。這個也以鑽石操作聞名,因為它的形狀。這個鑽石操作包含你想讀的句柄(<SESAME>)[4]。使用STDID句柄讀用戶提供的答案, 如下:
[4]空鑽石操作<>, 將從命令行指定的所有檔案讀, 如果沒有指定, 從STDIN讀。(這是許多UNIX"過濾"程式的標準行為)
print STDOUT "Enter a number: "; #請求輸入一個數
$number = <STDIN>; #輸入一個數
print STDOUT "The number is $number"; #輸出這個數
你明白我們給你的例子嗎?在print語句中STDOUT做什麼?這就是你使用一個輸出句柄的方法之一。一個句柄可以作為print語句的第一個參數, 如果存在, 告訴往哪兒輸出。在例子中,句柄是冗餘的,因為輸出已經是STDOUT。對於輸入的預設是STDIN, 對於輸出的預設是STDOUT。(在班級例子的18行, 我們為避免使你混淆, 我們省略了。)
我們也有一件事使你不明白。如果你試上面的例子,你可以注意到你得到一個特別的空行。因為讀時沒有自動地從你的輸入行中刪除換行符(newline)(例如, 你輸入"9")。對於這些情況,當你想刪除換行符時,Perl提供chopchomp函式。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提供服務的,對於用戶來說,句柄等同於對象指針,但實際上句柄和指針根本不是一回事!

相關詞條

熱門詞條

聯絡我們