[八]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()
連讀的能力都沒有,需要借助本地方法
自然是沒有能力跳過和獲取可用個數的
所以仍舊是依賴的本地方法

public native long skip(long n) throws IOException;

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體系會越來越容易理解



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM