IO流總結
- 2020 年 6 月 1 日
- 筆記
IO流總結
生活中,你肯定經歷過這樣的場景。當你編輯一個文本文件,忘記了 ctrl+s ,可能文件就白白編輯了。當你電腦 上插入一個U盤,可以把一個影片,拷貝到你的電腦硬碟里。那麼數據都是在哪些設備上的呢?鍵盤、記憶體、硬 盤、外接設備等等。
我們把這種數據的傳輸,可以看做是一種數據的流動,按照流動的方向,以記憶體為基準,分為 輸入input 和 輸出 output ,即流向記憶體是輸入流,流出記憶體的輸出流。
Java中I/O操作主要是指使用 java.io 包下的內容,進行輸入、輸出操作。輸入也叫做讀取數據,輸出也叫做作寫 出數據。
一.java.io.File 類是文件和目錄路徑名的抽象表示,主要用於文件和目錄的創建、查找和刪除等操作。
1. File類說明
v 存儲在變數,數組和對象中的數據是暫時的,當程式終止時他們就會丟失.為了能夠永久的保存程式中創建的數據,需要將他們存儲到硬碟或光碟的文件中.這些文件可以移動,傳送,亦可以被其他程式使用.由於數據存儲在文件中,所以我們需要學習一個和文件有密切關係的類,叫做File類,將要掌握獲取文件的屬性以及刪除和重命名文件.最終如何向文件中寫入數據和從文件中讀取數據.
v File類關心的是在磁碟上文件的存儲.
v File類描述的是一個文件或文件夾。(文件夾也可以稱為目錄)
v 該類的出現是對文件系統的中的文件以及文件夾進行對象的封裝。可以通過對象的思想來操作文件以及文件夾。
v 可以用面向對象的處理問題,通過該對象的方法,可以得到文件或文件夾的資訊方便了對文件與文件夾的屬性資訊進行操作。
v 文件包含很多的資訊:如文件名、創建修改時間、大小、可讀可寫屬性等。
2. File類中常用的方法:
創建:
l createNewFile() 在指定位置創建一個空文件,成功就返回true,如果已存在就不創建然後返回false
l mkdir() 在指定位置創建目錄,這隻會創建最後一級目錄,如果上級目錄不存在就拋異常。
l mkdirs() 在指定位置創建目錄,這會創建路徑中所有不存在的目錄。
l renameTo(File dest) 重命名文件或文件夾,也可以操作非空的文件夾,文件不同時相當於文件的剪切,剪切時候不能操作非空的文件夾。移動/重命名成功則返回true,失敗則返回false。
刪除:
l delete() 刪除文件或一個空文件夾,如果是文件夾且不為空,則不能刪除,成功返回true,失敗返回false。
l deleteOnExit() 在虛擬機終止時,請求刪除此抽象路徑名表示的文件或目錄,保證程式異常時創建的臨時文件也可以被刪除
判斷:
l exists() 文件或文件夾是否存在。
l isFile() 是否是一個文件,如果不存在,則始終為false。
l isDirectory() 是否是一個目錄,如果不存在,則始終為false。
l isHidden() 是否是一個隱藏的文件或是否是隱藏的目錄。
l isAbsolute() 測試此抽象路徑名是否為絕對路徑名。
獲取:
l getName() 獲取文件或文件夾的名稱,不包含上級路徑。
l getPath() 返回絕對路徑,可以是相對路徑,但是目錄要指定
l getAbsolutePath() 獲取文件的絕對路徑,與文件是否存在沒關係
l length() 獲取文件的大小(位元組數),如果文件不存在則返回0L,如果是文件夾也返回0L。
l getParent() 返回此抽象路徑名父目錄的路徑名字元串;如果此路徑名沒有指定父目錄,則返回null。
l lastModified() 獲取最後一次被修改的時間。
文件夾相關:
l staic File[] listRoots() 列出所有的根目錄(Window中就是所有系統的盤符)
l list() 返回目錄下的文件或者目錄名,包含隱藏文件。對於文件這樣操作會返回null。
l list(FilenameFilter filter) 返回指定當前目錄中符合過濾條件的子文件或子目錄。對於文件這樣操作會返回null。
l listFiles() 返回目錄下的文件或者目錄對象(File類實例),包含隱藏文件。對於文件這樣操作會返回null。
l listFiles(FilenameFilter filter) 返回指定當前目錄中符合過濾條件的子文件或子目錄。對於文件這樣操作會返回null。
二.遞歸
遞歸的思想
以此類推是遞歸的基本思想。
具體來講就是把規模大的問題轉化為規模小的相似的子問題來解決。在函數實現時,因為解決大問題的方法和解決小問題的方法往往是同一個方法,所以就產生了函數調用它自身的情況。另外這個解決問題的函數必須有明顯的結束條件,這樣就不會產生無限遞歸的情況了。
遞歸的兩個條件
1.可以通過遞歸調用來縮小問題規模,且新問題與原問題有著相同的形式。(自身調用)
2.存在一種簡單情境,可以使遞歸在簡單情境下退出。(遞歸出口)
遞歸三要素:
1.一定有一種可以退出程式的情況;
2.總是在嘗試將一個問題化簡到更小的規模
3.父問題與子問題不能有重疊的部分
小貼士:遞歸一定要有條件限定,保證遞歸能夠停止下來,次數不要太多,否則會發生棧記憶體溢出。
三.IO的概述
1.1什麼是IO
Java中I/O操作主要是指使用 java.io 包下的內容,進行輸入、輸出操作。輸入也叫做讀取數據,輸出也叫做作寫
出數據。
1.2 IO的分類
根據數據的流向分為:輸入流和輸出流。
l 輸入流:把數據從其他設備上讀取到記憶體中的流。
l 輸出流:把數據從記憶體中寫出到其他設備上的流。
格局數據的類型分為:位元組流和字元流。
l 位元組流 :以位元組為單位,讀寫數據的流。
l 字元流 :以字元為單位,讀寫數據的流。
1.3 IO的流向說明圖解
1.4 頂級分類們
|
輸入流 |
輸出流 |
位元組流 |
位元組輸入流 InputStream |
位元組輸出流 OutputStream |
字元流 |
字元輸入流 Reader |
字元輸出流 Writer |
二.位元組流
2.1一切皆為位元組
一切文件數據(文本、圖片、影片等)在存儲時,都是以二進位數字的形式保存,都一個一個的位元組,那麼傳輸時一 樣如此。所以,位元組流可以傳輸任意文件數據。在操作流的時候,我們要時刻明確,無論使用什麼樣的流對象,底層傳輸的始終為二進位數據。
2.2 位元組輸出流【OutputStream】
java.io.OutputStream 抽象類是表示位元組輸出流的所有類的超類,將指定的位元組資訊寫出到目的地。它定義了位元組輸出流的基本共性功能方法。
l public void close() :關閉此輸出流並釋放與此流相關聯的任何系統資源。
l public void flush() :刷新此輸出流並強制任何緩衝的輸出位元組被寫出。
l public void write(byte[] b) :將 b.length位元組從指定的位元組數組寫入此輸出流。
l public void write(byte[] b, int off, int len) :從指定的位元組數組寫入 len位元組,從偏移量 offff開始輸出到此輸出流。
l public abstract void write(int b) :將指定的位元組輸出流。
注意: close方法,當完成流的操作時,必須調用此方法,釋放系統資源。
2.3 FileOutputStream類
OutputStream 有很多子類,我們從最簡單的一個子類開始。
java.io.FileOutputStream 類是文件輸出流,用於將數據寫出到文件。
構造方法
l public FileOutputStream(File file) :創建文件輸出流以寫入由指定的 File對象表示的文件。
l public FileOutputStream(String name) : 創建文件輸出流以指定的名稱寫入文件。
當你創建一個流對象時,必須傳入一個文件路徑。該路徑下,如果沒有這個文件,會創建該文件。如果有這個文件的數據。
2.4 位元組輸入流【InputStream】
java.io.InputStream 抽象類是表示位元組輸入流的所有類的超類,可以讀取位元組資訊到記憶體中。它定義了位元組輸入流的基本共性功能方法。
l public void close() :關閉此輸入流並釋放與此流相關聯的任何系統資源。
l public abstract int read() : 從輸入流讀取數據的下一個位元組。
l public int read(byte[] b) : 從輸入流中讀取一些位元組數,並將它們存儲到位元組數組 b中 。
注意:close方法,當完成流的操作時,必須調用此方法,釋放系統資源。
2.5 FileInputStream類
java.io.FileInputStream 類是文件輸入流,從文件中讀取位元組。
構造方法
l FileInputStream(File file) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 fifile命名。
l FileInputStream(String name) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。
當你創建一個流對象時,必須傳入一個文件路徑。該路徑下,如果沒有該文件,會拋出 FileNotFoundException 。
三.字元流
當使用位元組流讀取文本文件時,可能會有一個小問題。就是遇到中文字元時,可能不會顯示完整的字元,那是因為一個中文字元可能佔用多個位元組存儲。所以Java提供一些字元流類,以字元為單位讀寫數據,專門用於處理文本文件。
3.1 字元輸入流【Reader】
java.io.Reader 抽象類是表示用於讀取字元流的所有類的超類,可以讀取字元資訊到記憶體中。它定義了字元輸入流的基本共性功能方法。
l public void close() :關閉此流並釋放與此流相關聯的任何系統資源。
l public int read() : 從輸入流讀取一個字元。
l public int read(char[] cbuf) : 從輸入流中讀取一些字元,並將它們存儲到字元數組 cbuf中 。
3.2 FileReader類
java.io.FileReader 類是讀取字元文件的便利類。構造時使用系統默認的字元編碼和默認位元組緩衝區。
注意:
1. 字元編碼:位元組與字元的對應規則。Windows系統的中文編碼默認是GBK編碼表。 idea中UTF-8
2. 位元組緩衝區:一個位元組數組,用來臨時存儲位元組數據。
構造方法
l FileReader(File file) : 創建一個新的 FileReader ,給定要讀取的File對象。
l FileReader(String fileName) : 創建一個新的 FileReader ,給定要讀取的文件的名稱。
當你創建一個流對象時,必須傳入一個文件路徑。類似於FileInputStream 。
3.3 字元輸出流【Writer】
java.io.Writer 抽象類是表示用於寫出字元流的所有類的超類,將指定的字元資訊寫出到目的地。它定義了位元組輸出流的基本共性功能方法。
l void write(int c) 寫入單個字元。
l void write(char[] cbuf) 寫入字元數組。
l abstract void write(char[] cbuf, int off, int len) 寫入字元數組的 某一部分,offff數組的開始索引,len寫的字元個數。
l void write(String str) 寫入字元串。
l void write(String str, int off, int len) 寫入字元串的某一部分,offff字元串的開始索引,len寫的字元個數。
l void flush() 刷新該流的緩衝。
l void close() 關閉此流,但要先刷新它。
3.4 FileWriter類
java.io.FileWriter 類是寫出字元到文件的便利類。構造時使用系統默認的字元編碼和默認位元組緩衝區。
構造方法
l FileWriter(File file) : 創建一個新的 FileWriter,給定要讀取的File對象。
l FileWriter(String fileName) : 創建一個新的 FileWriter,給定要讀取的文件的名稱。
當你創建一個流對象時,必須傳入一個文件路徑,類似於FileOutputStream。
關閉和刷新
因為內置緩衝區的原因,如果不關閉輸出流,無法寫出字元到文件中。但是關閉的流對象,是無法繼續寫出數據的。如果我們既想寫出數據,又想繼續使用流,就需要 flush 方法了。
l flush :刷新緩衝區,流對象可以繼續使用。
l close :先刷新緩衝區,然後通知系統釋放資源。流對象不可以再被使用了
注意:即便是flflush方法寫出了數據,操作的最後還是要調用close方法,釋放系統資源。
四.IO處理異常
之前的入門練習,我們一直把異常拋出,而實際開發中並不能這樣處理,建議使用 try…catch…finally 程式碼
塊,處理異常部分。
JDK7的處理(擴展知識點了解內容)
還可以使用JDK7優化後的 try-with-resource 語句,該語句確保了每個資源在語句結束時關閉。所謂的資源
(resource)是指在程式完成後,必須關閉的對象。
五.屬性集
5.1 概述
java.util.Properties 繼承於 Hashtable ,來表示一個持久的屬性集。它使用鍵值結構存儲數據,每個鍵及其對應值都是一個字元串。該類也被許多Java類使用,比如獲取系統屬性時, System.getProperties 方法就是返回一個 Properties 對象。
5.2 Properties類
構造方法
l public Properties() :創建一個空的屬性列表。
基本的存儲方法
l public Object setProperty(String key, String value) : 保存一對屬性。
l public String getProperty(String key) :使用此屬性列表中指定的鍵搜索屬性值。
public Set<String> stringPropertyNames() :所有鍵的名稱的集合。
與流相關的方法
l public void load(InputStream inStream) :從位元組輸入流中讀取鍵值對。
參數中使用了位元組輸入流,通過流對象,可以關聯到某文件上,這樣就能夠載入文本中的數據了。文本數據格式:
filename=a.txt
length=209385038
location=D:\a.txt
注意:文本中的數據,必須是鍵值對形式,可以使用空格、等號、冒號等符號分隔。