檔案IO流
- 前言
- 檔案File類
- 構造方法
- 成員方法
- 遞回
- IO流概述
- IO流常用基類
- 位元組流的抽象基類
- 1.InputStream
- 2.OutputStream
- 字符流的抽象基類
- 字符流
- 字串中的編碼解碼問題
- 1.InputStreamReader
- 2.OutputStreamWriter
- 字符緩沖流
- 其他特殊流
- 列印流
- 物件序列化流
- 物件反序列化流
- Properties
- IO流常見面試題
- 總結(附猜拳小游戲代碼)
前言
??近期學習了IO流,Java為I/O提供了強大的而靈活的支持,使其更廣泛地應用到檔案傳輸和網路編程中,為了幫助大家更好的學習,博主對IO流做了一下知識點回顧和總結,希望能夠幫助到大家的學習,歡迎各位和博主進行交流 !

檔案File類
概述
??在學習IO流之前,我們需要了解一個File類檔案,為什么要了解它呢?
??原因:IO流操作中大部分都是對檔案進行操作,所以Java就提供了一個File類供我們來操作檔案,File是檔案和目錄(檔案夾)路徑名的抽象表現形式
構造方法
??知道了,File的概述,接下來我們去了解它的構造方法:
??1.File(String pathName)
????根據字串路徑創建一個File物件
??2.File(String parent,String child)
????根據字串父級路徑和子級路徑創建File物件
??3. File(File parent,String child)
????根據File型別父級路徑和字串子級路徑創建File物件
成員方法
??再跟隨博主走進它的成員方法,關于File的成員方法,我在這里總結了它的6大功能:
1.創建功能:
??1.boolean createNewFile()
創建一個新檔案,如果存在就回傳false
??2.boolean mkdir()
創建檔案夾,如果存在一樣的檔案夾,就回傳false
??3.boolean mkdirs()
創建多個檔案夾,如果父類檔案夾不存在,會幫你自動創建出來,如果存在一樣的檔案夾,則回傳false
??4.注意
如果你創建檔案或檔案夾忘了寫路徑,那么默認在當前路徑創建
2.洗掉功能:
??public boolean delete()
??注意:
??要洗掉一個檔案夾,請注意該檔案內不能包含檔案或者檔案夾
Java中洗掉不走回收站
3.重命名功能:
??public boolean renameTo(File dest)
??如果路徑名相同,就是改名
??如果路徑名不同,就是改名并剪切
例子
??//創建一個檔案物件
?? File file = new File(“F:\IDEA\syy.txt”);
?? File file1 = new File(“F:\IDEA\sys.txt”);
??System.out.println(file.renameTo(file1));
4.判斷功能:
??1).public boolean isDirectory()
????判讀是否是檔案夾
??2).public boolean isFile()
????判斷是否是檔案
??3).public boolean exists()
????判斷檔案或檔案夾是否存在
??4).public boolean canRead()
????判斷是否可讀
??5).public boolean canWrite()
????判斷是否可寫
??6).public boolean isHidden()
????判斷檔案或檔案夾是否隱藏
5.獲取功能:
A.基本獲取功能:
??a. public String getAbsolutePath()
???? 獲取絕對路徑
?? b. public String getPath()
????獲取構造方法中的路徑
??c. public String getName()
????獲取檔案或檔案夾的名稱
??d. public long length()
????獲取長度–位元組數-可以獲取檔案的大小進行判斷
??e. publlic long lastModifiled()
????獲取最后一次修改的時間,回傳毫秒值,可以判斷修改過幾次
B.高級獲取功能:
??1).public String[] list()
????獲取目錄下所有內容,回傳字串陣列
??2).public File[] listFiles()
????獲取目錄下所有內容,回傳File物件陣列
6.檔案過濾功能:
??1).想獲取的時候就滿足條件,要實作檔案過濾介面
??2).public String[] listFiles (new FilenameFilter)
遞回
??再這里我們來講一種遞回的方法,至于用來干什么呢,那么就是遍歷目錄下所有的檔案:
遞回概述:
??方法定義呼叫本身的現象
注意事項
1.遞回一定要有出口
2.遞回的次數不能太多,否則就記憶體溢位
3.構造方法不能遞回使用
案例
不死神兔案例
洗掉指定目錄下的指定后綴名檔案
洗掉指定目錄下所以檔案和檔案夾
IO流概述
1.IO流用來處理設備之間的資料傳輸,上傳檔案和下載檔案
2.按照資料流向:
a.輸入流
資料從外部流入寫的程式
b.輸出流
資料從程式流到外面
3.按照資料型別分類:
a.位元組流
?位元組輸入流
讀取資料
?位元組輸出流
寫入資料
b.字符流
?2或3個位元組=1個字符
?字符輸入流
讀取資料
?字符輸出流
寫入資料
4.到底使用哪種型別的流呢?
如果操作的資料是文本檔案,就用記事本打開,能讀懂的就用字符流,不能讀懂的就用位元組流,什么也不知道的就用位元組流
IO流常用基類
位元組流的抽象基類
1.InputStream
a.讀取資料
位元組輸入流
b.子類
FileInputStream
●構造方法
? FileInputStream(String name)
創建位元組輸入流物件,帶檔案路徑或名稱
●方法
? public int read()
此輸入流中讀取一個位元組,如果已到檔案末尾,則回傳-1
? public int read(byte [ ] b)
一次讀取一個位元組陣列,回傳讀取位元組數的個數,如果已到檔案末尾,則回傳-1
c.位元組輸入流操作步驟
1.創建位元組輸入流物件
2.呼叫read( )方法讀取資料,并把資料顯示在控制臺
3.釋放資源
d.位元組緩沖輸入流
1).作用
提高讀取效率
2).格式
BufferedInputStrearm(FileInputStream)
3).舉例
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\IDEA\\視頻.avi"));
2.OutputStream
a.寫入資料
位元組輸出流
b.位元組流寫資料同時處理例外的重要步驟
1.將創建位元組流物件和寫出資料的代碼放在try中
2.在catch中捕獲IOException例外
3.在finally中進行釋放資源
1.子類
FileOutputStream
●構造方法:
? FileOutStream(String name)
創建一個向具有指定名稱的檔案中寫入資料的輸出檔案流
? FileOutStream(File file)
創建一個向指定File物件表示的檔案中寫入資料的檔案輸出流
●方法:
? public void close()
關閉次檔案輸出流并釋放此流有關的所有系統資源
為什么一定要用close呢?
1).讓流物件變成垃圾,這樣就可以唄垃圾收器回收了
2).通知系統去釋放跟該檔案相關的資源
? public void write(byte[ ] b)
寫入一個位元組陣列
? public void write(byte[ ] b,int off,int len)
寫入一個字符陣列的一部分,off索引開始,len索引結束
? public void write (int b)
寫入一個位元組
●如何實作資料的追加寫入?
用構造方法帶第二引數是true即可
FileOutStream fos =new FileOutStream("j.txt",true);
●如何實作資料的換行?
1).windows
添加一個\r\n
例如: fos.write(" \r\n".getBytes);
2).linux
\n
3).Mac
\r
2.位元組輸出流的操作步驟
△.創建位元組輸出流物件
△.寫入資料
△.釋放資源
字符流的抽象基類
字符流
為什么會出現字符流?
1.?(?????)?字符流的介紹:
由于位元組流操作中文不是特別的方便,所以Java就提供字符流
字符流 = 位元組流 + 編碼表
2.?(?????)?中文的位元組存盤方式:
a.用位元組流復制文本檔案時,文本檔案也會有中文,但是沒有問題
b.原因是最終底層操作會自動進行位元組拼接成中文,如何識別是中文的呢?
c.漢字在存盤的時候,無論選擇哪種編碼存盤,第一個位元組都是負數
重繪和關閉方法
字串中的編碼解碼問題
相關方法:

??字符流中和編碼解碼問題相關的兩個類:
1.InputStreamReader
2.OutputStreamWriter
●InputStreamReader:
a.是從位元組流到字符流的橋梁
b.它讀取位元組,并使用指定的編碼將其解碼為字符
c.它使用的字符集可以有名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集
●OutputStreamWriter:
a.是從字符流到位元組流的橋梁
b.使用指定的編碼將寫入的字符編碼為位元組
c.它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集
構造方法:

字符流讀取資料的2種方式:
??1.int read() :一次讀一個字符資料
??2.int read(char [ ] cbuf) : 一次讀一個字符陣列資料
字符緩沖流
介紹:
BufferedWriter:將文本寫入字符輸出流,緩沖字符,以提供單個字符,陣列和字串的高效寫入,
可以指定緩沖區大小,或者可以接受默認大小,默認值足夠大,可用于大多數用途
BufferedReader:從字符輸入流讀取文本,緩沖字符,以提供字符,陣列和行的高效讀取,
可以指定緩沖區大小,或者可以使用默認大小, 默認值足夠大,可用于大多數用途
特有功能
??BufferedWriter:
????void newLine( ) : 寫一行行分隔符,行分隔符字串由系統屬性定義
??BufferedReader:
????String readLine( ) : 讀一行文字,結果包含行的內容的字串,不包括任何終止字符如果流的結尾已經到達,則為null,
其他特殊流
列印流

物件序列化流
-
物件序列化介紹:
??1.物件序列化:就是將物件保存到磁盤中,或者在網路中傳輸物件
??2.這種機制就是使用一個位元組序串列示一個物件,該位元組序列包含:
??物件的型別、物件的資料和物件中存盤的屬性等資訊
??位元組序列寫到檔案之后,相當于檔案中持久保存了一個物件的資訊
??反之,該位元組序列還可以從檔案中讀取回來,重構物件,對它進行反序列化 -
物件序列化流: ObjectOutputStream
??將Java物件的原始資料型別和圖形寫入OutputStream, 可以使用ObjectInputStream讀取(重構)物件, 可以通過使用流的檔案來實作物件的持久存盤, 如果流是網路套接字流,則可以在另一個主機上或另一個行程中重構物件
構造方法:

序列化物件的方法:

注意事項: -
一個物件要想被序列化,該物件所屬的類必須必須實作Serializable 介面
-
Serializable是一個標記介面,實作該介面,不需要重寫任何方法
物件反序列化流
ObjectInputStream:反序列化先前使用
ObjectOutputStream:撰寫的原始資料和物件
構造方法

反序列化物件的方法

serialVersionUID&transient
serialVersionUID
- 用物件序列化流序列化了一個物件后,假如我們修改了物件所屬的類檔案,讀取資料會不會出問題呢?
- 會出問題,會拋出InvalidClassException例外
- 如果出問題了,如何解決呢?
- 重新序列化
- 給物件所屬的類加一個serialVersionUID
- private static final long serialVersionUID = 42L;
transient
- 如果一個物件中的某個成員變數的值不想被序列化,又該如何實作呢?
- 給該成員變數加transient關鍵字修飾,該關鍵字標記的成員變數不參與序列化程序
Properties
Properties介紹
- 是一個Map體系的集合類
- Properties可以保存到流中或從流中加載
- 屬性串列中的每個鍵及其對應的值都是一個字串
作為Map集合的特有方法:

Properties和IO流相結合的方法:

IO流常見面試題
1.位元組流和字符流哪個好?怎么選擇?
??大多數情況下使用位元組流會更好,因為大多數時候 IO 操作都是直接操作磁盤檔案,所以這些流在傳輸時都是以位元組的方式進行的(圖片等都是按位元組存盤的)
??如果對于操作需要通過 IO 在記憶體中頻繁處理字串的情況使用字符流會好些,因為字符流具備緩沖區,提高了性能,
2. 什么是緩沖區?有什么作用?
??緩沖區就是一段特殊的記憶體區域,很多情況下當程式需要頻繁地操作一個資源(如檔案或資料庫)則性能會很低,所以為了提升性能就可以將一部分資料暫時讀寫到快取區,以后直接從此區域中讀寫資料即可,這樣就顯著提升了性,
??對于 Java 字符流的操作都是在緩沖區操作的,所以如果我們想在字符流操作中主動將緩沖區重繪到檔案則可以使用 flush() 方法操作,
3.字符流和位元組流有什么區別?
??字符流和位元組流的使用非常相似,但是實際上位元組流的操作不會經過緩沖區(記憶體)而是直接操作文本本身的,而字符流的操作會先經過緩沖區(記憶體)然后通過緩沖區再操作檔案
4.什么是Java序列化,如何實作Java序列化?
??序列化就是一種用來處理物件流的機制,將物件的內容進行流化,可以對流化后的物件進行讀寫操作,可以將流化后的物件傳輸于網路之間,序列化是為了解決在物件流讀寫操作時所引發的問題
??序列化的實作:將需要被序列化的類實作Serialize介面,沒有需要實作的方法,此介面只是為了標注物件可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(物件流)物件,再使用ObjectOutputStream物件的write(Object obj)方法就可以將引數obj的物件寫出
5. PrintStream、BufferedWriter、PrintWriter的比較?
??PrintStream類的輸出功能非常強大,通常如果需要輸出文本內容,都應該將輸出流包裝成PrintStream后進行輸出,它還提供其他兩項功能,與其他輸出流不同,PrintStream 永遠不會拋出 IOException;而是,例外情況僅設定可通過 checkError 方法測驗的內部標志,另外,為了自動重繪,可以創建一個 PrintStream
??BufferedWriter:將文本寫入字符輸出流,緩沖各個字符從而提供單個字符,陣列和字串的高效寫入,通過write()方法可以將獲取到的字符輸出,然后通過newLine()進行換行操作,BufferedWriter中的字符流必須通過呼叫flush方法才能將其刷出去,并且BufferedWriter只能對字符流進行操作,如果要對位元組流操作,則使用BufferedInputStream
??PrintWriter的println方法自動添加換行,不會拋例外,若關心例外,需要呼叫checkError方法看是否有例外發生,PrintWriter構造方法可指定引數,實作自動重繪快取(autoflush)
6. BufferedReader屬于哪種流,它主要是用來做什么的,它里面有那些經典的方法?
??屬于處理流中的緩沖流,可以將讀取的內容存在記憶體里面,有readLine()方法,它,用來讀取一行
7.什么是節點流,什么是處理流,它們各有什么用處,處理流的創建有什么特征?
??節點流: 直接與資料源相連,用于輸入或者輸出
??處理流:在節點流的基礎上對之進行加工,進行一些功能的擴展
??處理流的構造器必須要 傳入節點流的子類
8.流一般需要不需要關閉,如果關閉的話在用什么方法,一般要在那個代碼塊里面關閉比較好,處理流是怎么關閉的,如果有多個流互相呼叫傳入是怎么關閉的?
??流一旦打開就必須關閉,使用close方法
??放入finally陳述句塊中(finally 陳述句一定會執行)
??呼叫的處理流就關閉處理流
??多個流互相呼叫只關閉最外層的流
總結(附猜拳小游戲代碼)

??通過上面的知識點回顧,我們能夠了解到IO流的兩種方式,一個是位元組流,一種是字符流,位元組流是可以復制任意檔案的資料,而字符流只能復制文本資料,雖然它能夠使用復制圖片視頻,但不能顯示,
??最后給大家附上一個小游戲的參考代碼,有興趣的可以下載試玩一下,還是蠻有趣的,
鏈接:https://pan.baidu.com/s/1v4iORhRjr-f3WDHJ9pamvw
提取碼:yy52
鏈接代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300558.html
標籤:其他
上一篇:【小Y學演算法】??每日LeetCode打卡??——32. 路徑總和
下一篇:【游戲開發創新】自學Blender建模,自制孔明燈,在Unity中點亮整個星空,愿新年,勝舊年(Unity | 建模 | 粒子系統 | 預設)
