[八]JavaIO之FileInputStream 與 FileOutputStream


接下來介紹 FileInputStream  和 FileOutputStream
如今看名字應該能夠看得出來:
他就是從一個文件中讀取數據
或者將數據寫入到一個文件中

FileInputStream

既然是從文件讀取數據,那麼天然要記錄文件自己的信息
因此有文件描述符 fd以及 path路徑名
顯然,文件描述符是對文件最直接的描述
若是是使用文件描述符做爲參數的話,path的值將會是null
image_5b9859e0_27a4

image_5b9859e1_472f 

nio的東西,暫時不說了 數組


構造方法
FileInputStream既然是從文件讀取數據
那麼構造方法的首要做用也就是要惟一肯定一個文件
根據以前的文章,要麼使用File描述,要麼可使用String的路徑名,再或者使用文件描述符能夠定位文件
因此,FileInputStream的構造方法也就這三種形式
image_5b9859e1_4d32
經過String的版本能夠發現,實際上使用的仍是File版本的方法
image_5b9859e1_3f2f
File版本的方法會設置fd 和 path的值
image_5b9859e1_75b

而文件描述符版本的卻不會設置path
image_5b9859e1_30db
剛纔也說了FileInputStream(String name) 是調用的File類型入參的構造方法
從上面的代碼也看得出來,實際上幹活的也就只是另外的兩個方法
他們都有一個fd.attach(this)  關於這個點,能夠查看文件描述符章節中說到的attach方法
是爲了把全部的跟某個文件描述符相關的流都記錄下來,畢竟一個文件可能被多個流打開
還須要注意的是
FileInputStream(FileDescriptor fdObj) 版本直接賦值參數到fd
FileInputStream(File file)  每次都是new FileDescriptor();




read方法
read方法讀取一個字節
帶數組參數的read方法將數據讀取到字節數組中,而且返回實際讀取的個數
跟InputStream是同樣的
看得出來,如同咱們以前說過的那樣,文件的讀寫操做依賴於操做系統,因此
全部的read都歇菜了,最終依賴的都是本地方法

還有一個須要時刻記住的是,read 阻塞選手
image_5b9859e1_5933


skip(long n)  available()
連讀的能力都沒有,須要藉助本地方法
天然是沒有能力跳過和獲取可用個數的
因此仍舊是依賴的本地方法

this

public native long skip(long n) throws IOException; app

public native int available() throws IOException;

Close方法
FileInputStream打開的但是實實在在的資源
因此close方法確定是須要作些事情關閉資源的
註釋中說的很清楚
關閉這個文件輸入流而且釋放全部與這個流相關的系統資源
若是這個流有關聯的chanel ,那麼也會關聯這個channel
以下圖所示源代碼中
他是經過fd.closeAll()   方法來執行所謂的"釋放全部相關資源"
image_5b9859e1_5cc7
看一個例子
image_5b9859e1_cf2
image_5b9859e1_3ae0
在文件描述符一章節中,咱們還記得fd.closeAll()  方法來執行所謂的"釋放全部相關資源"
那不是釋放了全部的麼?
爲何同一個File還能夠打開多個流,關閉不受影響呢?

根本在於上面說到的構造方法中

FileInputStream(FileDescriptor fdObj) 版本直接賦值參數到fd
FileInputStream(File file)  每次都是new FileDescriptor();
他們對於使用File構造的,他們的fd每次都是新建的!!!!!
因此說不受影響的
closeAll 的是同一個fd的


getFD()   getChannel() 
getFD()   getChannel()  就是返回他們的值
若是fd不存在,拋出異常
從構造方法能夠看得出來, 必然會有一個fd
getChannel nio的後續再說,沒有就建立一個
 
image_5b9859e1_2df5
image_5b9859e1_7589



FileOutputStream

FileOutputStream 用於寫入諸如圖像數據之類的原始字節的流
若是要寫入字符流,請考慮使用 FileWriter
FileOutputStream的字段除了append之外,跟FileInputStream同樣的, 含義做用 也是同樣的
image_5b9859e1_3605
append 表示字節寫入文件末尾處,而不是寫入文件開始處,由於 文件輸出字節流默認是數據寫入文件開始部位
就像剛纔說的那樣,字段除了append之外,跟FileInputStream是同樣的,含義也是同樣的
進而,構造方法也是同樣,只不過多了一個參數  append
這個boolean 類型的參數,正是用來設置append 標誌是不是追加寫

方法的內容都差很少的,咱們不在詳細介紹
image_5b9859e1_1da


write方法
write方法仍是家族遺傳的,本質不變
直接寫入一個字節,或者從數組中寫入字節到文件
write(int) 將指定字節寫入此文件輸出流
write(byte[] b)  將 b.length 個字節從指定 byte 數組寫入此文件輸出流中
write(byte[] b,int off, int len)   將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此文件輸出流
和輸入同樣,藉助於操做系統,,依賴於本地方法
image_5b9859e1_168f



getFD()   getChannel()   close()  和 FileInputStream中的如出一轍
代碼都是同樣的,再也不贅述


再一次的介紹了一對成員,你會發現越日後看越簡單,由於他們的套路大多數是同樣的
因此只須要自頂而下的瞭解清楚各個邏輯組成部分的含義功能
整個IO體系會愈來愈容易理解
相關文章
相關標籤/搜索