當(dāng)應(yīng)用程序請(qǐng)求打開(kāi)或操作文件時(shí),操作系統(tǒng)會(huì)為該應(yīng)用程序提供一個(gè)文件列表,并分配一個(gè)非負(fù)整數(shù)作為索引號(hào)。這個(gè)索引號(hào)就像地址或指針,用于在內(nèi)存中定位文件數(shù)據(jù)。在類(lèi)unix系統(tǒng)中,這個(gè)索引號(hào)被稱(chēng)為文件描述符,而在windows系統(tǒng)中則被稱(chēng)為句柄,用于標(biāo)識(shí)各種對(duì)象。
文件描述符是類(lèi)unix系統(tǒng)中用于描述任何資源對(duì)象的概念,類(lèi)似于Java中的class對(duì)象。在Java中,文件描述符的概念通過(guò)java.io.FileDescriptor類(lèi)來(lái)抽象。對(duì)于FileInputStream、FileOutputStream和RandomaccessFile,使用handle來(lái)表示底層的文件句柄;而對(duì)于ServerSocket和Socket,則使用fd來(lái)表示底層的文件句柄。文件描述符的無(wú)效值為-1。
文件描述符類(lèi)的實(shí)例用作與基礎(chǔ)機(jī)器相關(guān)的某種結(jié)構(gòu)的不透明句柄,用于表示打開(kāi)的文件、套接字或其他字節(jié)源或接收者。主要用于創(chuàng)建包含該結(jié)構(gòu)的FileInputStream或FileOutputStream。應(yīng)用程序不應(yīng)自行創(chuàng)建文件描述符,因?yàn)樗鼈兪怯?a href="http://www.albr2v3.cn/help/index.php/tag/%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f" title="操作系統(tǒng)flickr.photos.notes.edit target="_blank">操作系統(tǒng)提供的。
文件描述符就像電話號(hào)碼,通過(guò)它可以定位到具體的文件或資源,但它本身并不是文件或資源。應(yīng)用程序在需要服務(wù)時(shí),將文件描述符傳遞給操作系統(tǒng),由操作系統(tǒng)處理具體操作。文件描述符是操作系統(tǒng)管理和維護(hù)的抽象概念,應(yīng)用程序通過(guò)請(qǐng)求操作系統(tǒng)來(lái)進(jìn)行文件操作。
在Java中,F(xiàn)ileDescriptor類(lèi)內(nèi)置了三個(gè)文件描述符,分別是標(biāo)準(zhǔn)輸入(in)、標(biāo)準(zhǔn)輸出(out)和標(biāo)準(zhǔn)錯(cuò)誤(err)。它們的具體值分別是0、1和2,這些值是操作系統(tǒng)層面的描述。在Linux中,每個(gè)進(jìn)程啟動(dòng)時(shí)會(huì)打開(kāi)這三個(gè)文件。
文件描述符通常不直接使用,而是通過(guò)System.in、System.out和System.err來(lái)訪問(wèn)。這些標(biāo)準(zhǔn)輸入輸出是共享的,但在Java的多線程環(huán)境中需要特別處理。在系統(tǒng)初始化之前,線程不能使用這些對(duì)象。System類(lèi)在加載時(shí)會(huì)將它們初始化為null,之后通過(guò)initializeSystemClass方法進(jìn)行初始化。
initializeSystemClass方法使用這三個(gè)文件描述符創(chuàng)建FileInputStream和FileOutputStream對(duì)象。對(duì)于out和err,根據(jù)編碼轉(zhuǎn)換為PrintStream,然后通過(guò)本地方法進(jìn)行設(shè)置。因此,應(yīng)用程序不直接創(chuàng)建文件描述符,而是通過(guò)系統(tǒng)調(diào)用和本地方法來(lái)操作和使用它們。