文章目錄
1.什麼是IO流?
IO流:I : Input:輸入:讀
O : Output:輸出:寫
通過IO可以完成硬盤文件的讀和寫。
2.流的分類方式?
分類方式:
1.以內存作爲參照物:
1.輸入流:磁盤——>內存:往內存中去,叫做輸入(Input)。或者叫做讀(Read)。
2.輸出流:內存——>磁盤:從內存中出來,叫做輸出(Output)。或者叫做寫(Write)。
2.讀取數據方式不同:
1.字節流:按照字節的方式讀取數據,一次讀取1個字節bytee,等同於一次讀取8個二進制位。
這種流是萬能的,什麼類型的文件都可以讀取。包括:文本文件,圖片,聲音文件,視頻文件等…
假設文件file1.txt,採用字節流的話是這樣讀的:
a中國bc張三fe
第一次讀:一個字節,正好讀到’a’
第二次讀:一個字節,正好讀到’中’字符的一半。
第三次讀:一個字節,正好讀到’中’字符的另外一半。
2.字符流:按照字符的方式讀取數據,一次讀取一個字符,這種流不能讀取:圖片、聲音、視頻等文件。只能讀取純
文本文件(能以記事本方式打開編輯的),連word文件都無法讀取。
假設文件file1.txt,採用字符流的話是這樣讀的:
a中國bc張三fe
第一次讀:'a’字符('a’字符在windows系統中佔用1個字節。)
第二次讀:'中’字符('中’字符在windows系統中佔用2個字節。)
總結:流的分類:
1.輸入流 2.輸出流 3.字節流 4.字符流
3. IO流四大家族?
1.java.io.InputStream 字節輸入流(讀)(萬能)
2.java.io.OutputStream 字節輸出流(寫)(萬能)
3.java.io.Reader 字符輸入流(讀)(普通文本)
4.java.io.Writer 字符輸出流(寫)(普通文本)
它們都是抽象類。(abstract class)
所有的流都實現了:
java.io.Closeable接口,都是可關閉的,都有close()方法。
流是一個管道,是內存和硬盤之間的通道,用完之後一定要關閉,不然會耗費(佔用)很多資源。
所有的輸出流都實現了:
java.io.Flushable接口,都是可刷新的,都有flush()方法。
輸出流在最終輸出之後,一定要記得flush()刷新一下。這個刷新表示將通道/管道當中剩餘未輸出的數據強行輸出完(清空管道!)
刷新的作用就是清空管道。
注意:如果沒有flush()可能會導致丟失數據。
重點:在java中只要“類名”以Stream結尾的都是字節流。以“Reader/Writer”結尾的都是字符流。
4.常用的流有哪些?
文件專屬:
java.io.FileInputStream(掌握)
java.io.FileOutputStream(掌握)
java.io.FileReader
java.io.FileWriter
轉換流:(將字節流轉換成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
緩衝流專屬:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
數據流專屬:
java.io.DataInputStream
java.io.DataOutputStream
標準輸出流:
java.io.PrintWriter
java.io.PrintStream(掌握)
對象專屬流:
java.io.ObjectInputStream(掌握)
java.io.ObjectOutputStream(掌握)
5.FileInputStream?
文件字節輸入流:萬能:字節方式,輸入操作:讀:硬盤——> 內存。
方法:
1.read()方法:從輸入流讀取數據的下一個字節,返回int,如果沒有數據了,返回-1。
(效率太慢,可以用while循環,也還是效率低,不建議用)。
2.read(byte[] b):就是讀了幾個字節就返回這個數字,不是返回字節。讀了4個字節就返回4這個數字,而不是這4個字節是什麼。
3.close():關閉資源。
利用byte數組讀:
規定byte數組讀的長度,一次讀規定的長度,用read(byte[] b)輸出讀了多少字節,將數組轉換成字符串輸出。
數據讀完了再讀就返回-1。
可用while循環再進行改進,提高效率。
6.FileoutputStream?
文件字節輸出流:萬能:字節方式,輸出操作:寫:內存——> 磁盤。
1.write(byte[] b):將b個字節的數組寫入輸入流。(將字符串轉化成數組寫入輸出)
2.flush():徹底完成輸入清空緩存器。
3.close():關閉。
7.FileReader/FileWriter?
文件字符輸入流:普通文本:字符方式,輸入操作:讀:硬盤——> 內存。
利用讀char數組的方式:
FileWriter:
文件字符輸出流:普通文本:字符方式,輸出操作:寫:內存——> 硬盤。
8.InputStreamReader/OutputStreamWriter?
InputStreamReader:
文件字符輸入流:普通文本:字符方式,輸入操作:讀:硬盤——> 內存。
將字節流轉換成字符流:
InputStreamReader(FileInputStream in):裏面傳一個FileInputStream類型對象進行轉換。
OutputStreamWriter:同理:將字節流轉換成字符流:
OutputStreamWriter(FileOutputStream in):裏面傳一個FileOutputStream類型對象進行轉換。
9.BufferedReader/BufferedWriter?
BufferedReader:
文件字符輸入流:普通文本:字符方式,輸入操作:讀:硬盤——> 內存。
帶有緩衝區的字符輸入流。
使用這個流的時候不需要自定義char數組,或者說不需要自定義byte數組。自帶緩衝。
方法:
readLine():讀取一行,沒有數據輸出null
BufferedReader(InputStreamReader in)
BufferedReader(FileReader fr)
// 當一個流的構造方法中需要一個流的時候,這個被傳進來的流叫做:節點流。
// 外部負責包裝的這個流,叫做:包裝流,還有一個名字叫做:處理流。
// 像當前這個程序來說:FileReader就是一個節點流。BufferedReader就是包裝流/處理流。
// 對於包裝流來說,只需要關閉最外層流就行,裏面的節點流會自動關閉。(可以看源代碼。)
BufferedWriter同理:
文件字符輸出流:普通文本:字符方式,輸出操作:寫:內存——> 硬盤。
10.DataInputStream/DataOutputStream?
DataInputStream:
文件字節輸入流:萬能:字節方式,輸入操作:讀:硬盤——> 內存。
DataOutputStream寫的文件,只能使用DataInputStream去讀。並且讀的時候你需要提前知道寫入的順序。
讀的順序需要和寫的順序一致。纔可以正常取出數據。
DataOutputStream:
數據字節輸出流:萬能:字節方式,輸出操作:寫:內存——> 磁盤。
數據專屬的流。這個流可以將數據連同數據的類型一併寫入文件。注意:這個文件不是普通文本文檔。(這個文件使用記事本打不開。)
11.ObjectInputStream/ObjectOutputStream?
序列化反序列化:
參與序列化和反序列化的對象,必須實現Serializable接口。
通過源代碼發現,Serializable接口只是一個標誌接口
public interface Serializable {
}
起到標識的作用,標誌的作用,java虛擬機看到這個類實現了這個接口,可能會對這個類進行特殊待遇。
Serializable這個標誌接口是給java虛擬機參考的,java虛擬機看到這個接口之後,會爲該類自動生成
一個序列化版本號。
transient關鍵字表示遊離的,不參與序列化。
private transient String name; // name不參與序列化操作!
//java語言首先通過類名進行比對,如果類名不一樣,肯定不是同一個類。
//如果類名一樣,再怎麼進行類的區別?靠序列化版本號進行區分。
//IDEA工具自動生成序列化版本號。
//private static final long serialVersionUID = -7998917368642754840L;
//Java虛擬機看到Serializable接口之後,會自動生成一個序列化版本號。
//這裏沒有手動寫出來,java虛擬機會默認提供這個序列化版本號。
//這種自動生成的序列化版本號缺點是:一旦代碼確定之後,不能進行後續的修改,
// 建議將序列化版本號手動的寫出來。不建議自動生成
//凡是一個類實現了Serializable接口,建議給該類提供一個固定不變的序列化版本號。
12.PrintStream?
標準的字節輸出流。默認輸出到控制檯。
默認輸出控制檯,可改爲輸出指定文件:
控制檯輸出:
log文件輸出: