IO
輸入與輸出
無論是輸入還是輸出,執行操作的對象都是程序
- Input:讀,將外部數據輸入到程序
- output:寫,將程序數據輸出到外部文件
IO實現了內存與磁盤之間的交互,即軟-硬件交互,需要消耗大量的資源,所以無論是讀還是寫,都需要在完成操作之後關閉流對象,避免佔用過多資源
流的類別
以基本單位作爲分類
- 字節流:讀取數據的基本單位是字節。以下是字節流的父接口:
- 讀:InputStream
- 寫:outputStream
- 字符流:讀取數據的基本單位是字符,由於字符由字節組成,所以字符流的底層也是字節流。以下是字符流的父接口:
- 讀:reader
- 寫:writer
以構造器分類
- 節點流
- 包裝流:節點流增強
字節流和字符流的讀、寫類都是抽象類,我們實際用到的都是它們的子類
流的讀寫操作都是單向的,這是與RandomAccessFile的最大區別
字節流(以下均爲字節流)
字節流的常用子類
讀
- FileInputStream
- BufferInputStream
- ObjectInputStream
寫
- FileOutputStream
- BufferOutputStream
- ObjectOutputStream
普通字節輸入/輸出流
FileInputStream
常用API
- FileInputStream(File file):構造方法
- FileInputStream(String path):構造方法
- int read():從此文件中讀取一個字節的數據
- int read(byte[ ] b):將最多[b.length]個字節長度的數據從文件讀入[b]數組中
- int read(byte[ ] b,int off,int len):從[off]位置開始,將[len]個字節長度的數據讀入[b]數組中
- int read[基本數據類型]:讀取指定類型的數據,每次讀取的長度與指定類型相同,示例:readInt(int i)
- int available():返回值表示還剩餘多少字節未讀
- long skip(long n):跳過並丟棄n個字節的數據
- void close():將緩衝區刷新,並將其中所有內容輸出到文件,然後再關閉
FileOutputStream
常用API
- FileOutputStream(File file):通過傳入一個文件對象創建一個IO流對象
- FileOutputStream(File file,boolean append):[append]爲true表示文件末尾追加輸入新內容;反之,新內容會清空之前被寫入的內容,默認是false
- FileOutputStream(String path)
- FileOutputStream(String path,boolean append)
- void write(int b):向此文件中寫入指定字節
- void write(byte[] b)
- void write(byte b,int off,int len):從[off]位置開始,將[b]數組中的[len]個長度的字節寫入寫入文件
- void write[基本數據類型]:寫入指定類型的數據,每次寫入的長度與指定類型相同,示例:writeInt(int i)
- void flush():刷新緩衝流,將緩衝流中的內容寫入文件
- void close():將緩衝區刷新,並將其中所有內容輸出到文件,然後再關閉
緩衝流:程序數據—>緩衝流—>flush()—>文件
緩衝字節輸入/輸出流
字節流的加強版,用法與字節流相同,運行速度更快
- 讀:BufferedInputStream
- 寫:BufferedOutputStream
緩衝字節輸入/輸出流的特點
普通字節流:每讀取一次規定長度的字符就要與文件直接交互一次,假如有1000個字符,每次讀取一個字符,那麼就會發生1000次交互。
緩衝字符流:在內存中創建了一個緩衝區(只有程序可見),文件中的字節按照讀取規則被添加進緩衝區中,而不與程序直接交互;當緩衝區的空間被填滿之後,緩衝區將所有字節數據傳遞給程序。如此一來,減少了交互次數,提高了效率。
輸出流按照輸出規則將字節添加進緩衝區,緩衝區滿了之後再寫入文件
BufferedInputStream
常用API
- BufferedInputStream(InputStream inputStream)
- BufferedInputStream(InputStream inputStream,int size):自定義緩衝區的大小
其餘API均與FileInputStream相同
BufferedInputStream
常用API
- BufferedOutputStream(OutputStream outputStream)
- BufferedOutputStream(OutputStream outputStream,int size):自定義緩衝區的大小
其餘API均與FileOutputStream相同
對象流
顧名思義,以對象爲操作對象進行讀寫的流
- 讀:ObjectInputStream
- 寫:ObjectOutputStream
序列化:將對象轉化成字節的過程(對象類必須實現Serializable接口)
持久化:將字節存儲到文件系統中的過程
Serializable:沒有任何字段和方法,實現該接口的類可啓用序列化功能,未實現該接口的類不能進行序列化或者反序列化。
對象流的作用
多個用戶共享對象數據
對象流的特點
- !!!被傳輸的對象必須實現Serializable接口
- 寫之後、讀之前該對象類不能發生變化(字段名、字段個數、字段內容、方法名、方法個數、方法內容),除非指定serialVersionUID
關鍵字:transient
- 作用:在序列化時,會忽略被該關鍵字修飾的字段的屬性值
serialVersionUID:版本號,判斷對象類與流中的對象是否一致的標準。
- 若不指定,則會默認生成,每一次修改對象類都會導致版本號發生改變,所以這種情況下寫入對象之後不能修改對象類;
- 若指定,版本號不會隨對象類的修改而改變,所以這種情況下寫入對象之後可以修改對象類(字段、方法都可修改)
- 讀取到的字段比對象類多:多出來的字段被捨棄
- 讀取到的字段比對象類少:補上少的那部分字段,並設置默認值
ObjectInputStream
常用API
- ObjectInputStream(InputStream inputStream)
- int read():從此文件中讀取一個字節的數據
- int read(byte[ ] b):將最多[b.length]個字節長度的數據從文件讀入[b]數組中
- int read(byte[ ] b,int off,int len):從[off]位置開始,將[len]個字節長度的數據讀入[b]數組中
- int read[基本數據類型]:讀取指定類型的數據,每次讀取的長度與指定類型相同,示例:readInt(int i)
- Object readObject():讀取對象,需要進行強制類型轉換
- void close()
ObjectOutputStream
常用API
- ObjectOutputStream(OutputStream outputStream)
- void write(int b):向此文件中寫入指定字節
- v oid write(byte[] b)
- void write(byte b,int off,int len):從[off]位置開始,將[b]數組中的[len]個長度的字節寫入寫入文件
- void write[基本數據類型]:寫入指定類型的數據,每次寫入的長度與指定類型相同,示例:writeInt(int i)
- writeObject(Object o):寫入指定的對象,被寫入的對象類型默認轉換成Object
- void close()
字符流(以下均爲字符流)
字節流的常用子類
讀:
- InputStreamReader
- BufferedReader
寫:
- OutputStreamReader
- PrintWriter
普通字節輸入/輸出流
InputStreamReader
常用API
-
InputStreamReader(InputStream in)
-
InputStreamReader(InputStream in,Charset charset):以指定編碼方式創建對象(需要傳入一個編碼集對象)
-
InputStreamReader(InputStream in,String charsetName):以指定編碼方式創建對象(傳入對應編碼集的名稱)
-
int read():讀取單個字符
-
int read(char[] chars):將[chars.length]個長度的字符讀取到[chars]數組
-
int read(char[] chars,int off,int len):從數組的[off]位置開始,將[len]個長度的字符讀入[chars]數組
-
getEncoding():獲取此流使用的字符集的名稱
-
close()
所有轉義字符,包括空格都會被完整地讀取
OutputStreamWriter
常用API
-
OutputStreamWriter(OutputStream in)
-
OutputStreamWriter(OutputStream in,Charset charset):以指定編碼方式創建對象(需要傳入一個編碼集對象)
-
OutputStreamWriter(OutputStream in,String charsetName):以指定編碼方式創建對象(傳入對應編碼集的名稱)
-
int write(char c):寫入單個字符
-
int write(char[] chars):將[chars]中的內容寫入文件
-
int write(char[] chars,int off,int len):從[chars]數組的[off]位置開始,將[len]個長度的字符寫入文件
-
int write(String str):寫入一個字符串
-
int write(String str,int off,int len):從[str]字符串的[off]位置開始,將[len]個長度的字符寫入文件
-
getEncoding()
-
close()
-
flush():刷新緩衝流
緩衝字符輸入/輸出流
BufferedReader
常用API
-
!!!BufferedReader(Reader in):默認緩衝區大小
-
BufferedReader(Reader in,int size):自定義緩衝區大小
-
read(…):參照InputStreamReader
-
String readLine():整行讀取,當返回值爲null時表示讀取結束
PrintWriter
常用API
構造方法(極其重要):
- PrintWrite(File file)
- PrintWrite(File file,String charsetName)
- PrintWrite(String filePath)
- PrintWrite(String filePath,String charsetName)
- PrintWrite(OutputStream outputStream)
- PrintWrite(OutputStream outputStream,boolean autoFlush):默認爲false,自動刷新緩衝區(println()有效,print()無效)
- PrintWrite(Writer writer)
- PrintWrite(Writer writer,boolean autoFlush)
- 能指定字符集的,不能追加內容
- 能追加內容的,不能指定字符集
讀寫操作:
- write(…):參照OutputStreamWriter
- print(…):將指定字符串輸出到緩衝區中,執行之後需要刷新緩衝區才能將數據輸出到文件中(直接關閉流也可行)
- println(…):在print()的基礎上增加換行功能,使用該方法時必須刷新緩衝區(僅使用close()無效)
- append(char c):追加字符
- append(String str):追加字符串
- append(String str,int start,int end):截取[start]到[end]位置的字符串追加到文件中
print()和printl(…)均可以接收八大數據類型和String類型