[一]FileDescriptor文件描述符 標準輸入輸出錯誤 文件描述符

文件描述符

 
當應用程序請求打開或者操做文件時,操做系統爲應用程序設置一張文件列表,具體的實現形式此處不深刻說明
操做系統會提供給你一個非負整數,做爲一個索引號,它的做用就像地址或者說指針或者說偏移量
這個索引號就用來定位文件數據在內存中的位置.
這個概念在類Unix系統叫作文件描述符, linux把全部東西都被當作是文件,好比文件、目錄、進程、網絡socket、各類硬件設備等
這個概念在Windows下 稱之爲句柄, 句柄是Windows下各類對象的標識符, 好比文件、資源、菜單、光標、位圖等
那麼,如今你應該能夠理解文件描述符的含義了

文件描述符  之於文件系統(操做系統中的一切都是文件描述符 可使用文件描述符描述任何一個資源對象
就如同Class 之於java語言同樣(java中一切都是類,都是一個Class的實例,任何一個類都用Class對象的實例來描述

Java中使用FileDescriptor 來抽象文件描述符這一律念
package java.io;
image_5b923c62_6c7f
對於FileInputStream/FileOutputStream/RandomAccessFile,使用handle來表示底層的文件句柄
對於ServerSocket/Socket,使用fd來表示底層的文件句柄
FileDescriptor的fd和handle的無效值是-1


看下API的描述:
文件描述符類的實例用做與基礎機器有關的某種結構的不透明句柄
該結構表示開放文件、開放套接字或者字節的另外一個源或接收者。
文件描述符的主要實際用途是建立一個包含該結構的 FileInputStream 或 FileOutputStream。
 
應用程序不該建立本身的文件描述符。 

其實說白了,就是文件描述符的實例,就是用來表示文件的一個指針/索引. 操做系統經過這個值與應用程序交互
如同你的電話號碼同樣,在不少場景,他就至關於你,   雖然,他徹底不是你,
好比朋友想找你聊天,有人託你辦事,保險公司推銷等等,經過電話均可以定位到你
 
並且,你本身能造一個電話號碼麼?顯然不行,必須是運營商提供給你的
咱們的文件描述符,也是如此,應用程序不該該建立本身的文件描述符
他的構造方法,只能建立一個無效的文件描述符

不該該建立本身的文件描述符,能夠直接理解爲:
這東西是底層實現的內容,操做系統來傳遞給你
並且,對於文件的其餘的一些操做,最底層的實現也仍舊是操做系統來搞
這就至關於操做系統給你的一個指針,鑰匙
你須要服務的時候,拿給操做系統便可,具體到底怎麼玩,你管不上,也管不了
 
想要理解文件描述符只須要理解,文件的抽象概念是操做系統負責管理維護的
應用程序都是在請求操做系統幫忙,JVM也就是個應用程序
無論那個位置到底存放的是什麼,對於應用程序來講就是一個描述符
操做系統提供了一致性的接口訪問途徑,就是經過這個描述符
描述符背後究竟是什麼,操做系統屏蔽了這些東西
這樣子的實現,對應用程序程序員來講,就是不須要在關注他究竟是個什東西,操做系統來搞定
 
image_5b923c62_27aa
 

FileDescriptor中的三個描述符

FileDescriptor 內置了三個文件描述符 分別是  in   out  err
類型是FileDescriptor  這是java層面的描述
具體的值是 0  1   2  ,這是操做系統層面的描述
 
在linux 中, 每一個進程啓動時都打開3個文件(linux 中一切都是文件): 
* 標準輸入  0
* 標準輸出  1
* 標準錯誤  2
 
三個描述符,經過調用私有方法 standardStream進行建立初始化
建立一個FileDescriptor 而且,設置他的handle值
內部的set(fd)是一個本地方法
說白了,就是經過調用本地方法,得到操做系統對標準輸入/輸出/錯誤的三個文件描述符
 
image_5b923c63_6b43
 
 
image_5b923c63_409e
 
註釋中也說的很清楚,文件描述符通常不直接使用
經過使用System.in  System.out System.err
 

文件描述符在System類中的應用

在System 中   in  out err  都是 final  static的
標準的輸入輸出是共享,可是java是多線程的
所以它們必須受到特別的處理,在系統初始化完成以前,線程嚴禁使用這幾個特殊對象;
又由於這些對象都是靜態的,所以java的類加載機制會在System類加載的時候就會初始化,這就形成了一對矛盾;
爲解決這對矛盾,System在加載是將它們初始化爲null,等加在完成後,經過  initializeSystemClass
 
System中in out  err中的定義部分,全都是final static
註釋中也很明確的說明了 將會調用 initializeSystemClass  進行部分初始化工做
 
image_5b923c63_21ce
 
initializeSystemClass 方法的關鍵部位 以及 本地的setIn0 setOut0 setErr0
initializeSystemClass 方法對於這塊來講,主要就是
使用三個文件描述符  建立了 FileInputStream  以及 FileOutputStream
對於Out以及Err又根據encoding 轉換爲PrintStream
而後經過本地方法進行設置
因此說,那三個專門的文件描述符通常不直接使用
取而代之的則是使用文件描述符 初始化設置過的流對象
 
image_5b923c63_5566
 
 
應用程序不建立文件描述符, 都是由系統調用, 也就是本地方法來操做的
應用程序只是得到,  而後使用,  所謂使用,最終也仍是須要藉助於操做系統
是應用程序 操做文件 時 與操做系統進行交互時,必須的數據項 
相關文章
相關標籤/搜索