1.File類的使用
- File類的一個實例對應著磁盤上的文件或文件目錄。
- (必須熟悉)File的實例化(新建一個對象),常用的方法
- File類中只有新建,刪除,獲取路徑等方法,不包含讀寫文件的方法,此時需要使用使用下面說的IO流
- IO流的概述
-
IO流的分類(按不同方式有不同的分類,比如下面)
-
- (按)流向(分類):輸入流,輸出流
-
- (按)數據處理單位(分類): 字節流,字符流
-
- (按)流的角色(分類):節點流,處理流
-
IO的四個抽象基類:InputStream\OutputStream\Reader\Writer(實際中具體使用的都是這四個基類的子類)
- 節點流之:文件流(上面那四個抽象基類前面加File關鍵字)
FileInputStream \ FileOutputStream \ FileReader \ FileWriter
其中FileInputStream \ FileOutputStream可處理jpeg文件
FileReader \ FileWriter主要處理txt文件
(步驟)讀/寫數據的過程如下:
- 步驟1:創建File類的對象,作為讀取或寫出數據的端點
- 步驟2:創建相關的流的對象(并且將File對象作為參數傳進去,讀的時候必須真實存在,寫的時候File對象其實可以不存在,系統會幫著創建)
- 步驟3:讀取/寫出數據的過程
- 步驟4:關閉流資源
- 處理流之一:緩沖流(上面那四個抽象基類前面加Buffered關鍵字)
- BufferedInputStream \ BufferedOutputStream \ BufferedReader \ BufferedWriter
- 作用:實現更高效的讀寫數據的操作
- 處理流之二:轉換流(上面那四個抽象基兩兩拼接)
-
層次1:熟悉轉換流的使用
InputStreamReader輸入型的字節流轉化成輸出型的字符流
OutputStreamWriter輸入型的字符流轉化成輸出型的字節流
回憶下圖
-
層次2:(重點需要掌握)字符的編碼和解碼的過程,常用的字符集
-
- 解決相關的問題: 讀寫字符出現亂碼?本質原因為:使用的解碼集和編碼集不一致。
- 處理流之三:對象流(Object加四個抽象基類前兩個Stream流)
-
層次1:需要熟悉對象流的使用
-
- ObjectInputStream:反序列化需要使用的API(再用這個從文件里解密出來)
-
- ObjectOutputStream:序列化時候需要使用的API(先用這個寫到文件里)
-
層次2:對象的序列化機制
-
- 使用場景:不同的進程之間通信,客戶端(或瀏覽器端)與服務器端傳輸數據
-
- 自定義類要想實現序列化機制需要滿足的要求和注意點。
注意三個點
implements Serializable 實現Serializable接口
serialVersionUID 必須要自定義一個。
static int age; //如果定義為static,靜態的,后續無法正常序列化,反序列化會得到null。
transient//如果定義為瞬態的,后續無法正常序列化,反序列化會得到null。
快速舉例自定義的Person類
import java.io.Serializable;/*
* 為什么要寫implements Serializable?
* 如果不寫,會出現錯誤:java.io.NotSerializableException: IOTest.Person
* 這個錯誤表示你嘗試序列化一個類(在這個例子中是 IOTest.Person 類),
* 但是這個類沒有實現 java.io.Serializable 接口。
* 在Java中,要序列化一個對象,該對象的類必須實現 Serializable 接口,
* 否則當你嘗試將該對象寫入到輸出流(如 ObjectOutputStream)時,就會拋出 NotSerializableException 異常。
*
* 這類接口,就叫標識接口
* */
public class Person implements Serializable { //Serializable屬于一個標識接口static final long serialVersionUID = 676600868485450L;// 上面的serialVersionUID可以隨便寫個數字,這個編碼類似密碼一樣,注意一定要自己定義。// 如果自己不定義,系統會在后臺幫你默認定義一個serialVersionUID編碼,用于序列化+反序列化。// 這樣很危險,因為一旦自定義類的代碼被改寫,系統就會重新生成一個新的serialVersionUID編碼// 就會造成序列化用著一個“密碼”,反序列化用著一個新的“密碼”,運行起來就會直接報錯。String name;static int age; //定義為static,靜態的,無法正常序列化,等到反序列化則輸出為nulltransient long id; //定義為transient,瞬態的,無法正常序列化,等到反序列化則輸出為nullAccount acct ;public Person() {}public Person(String name, int age, long id) {this.name = name;this.age = age;this.id = id;}public Person(String name, int age, long id, Account acct) {this.name = name;this.age = age;this.id = id;this.acct = acct;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public long getId() {return id;}public void setId(long id) {this.id = id;}static class Account implements Serializable {double balance;static final long serialVersionUID = 6766005450L;public Account(double balance) {this.balance = balance;}@Overridepublic String toString() {return "Account{" +"balance=" + balance +'}';}}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", id=" + id +", acct=" + acct +'}';}
}
使用時,調用Person類并構建對象,并賦值。 使用p2再解碼解碼出來。
Person p1 = new Person("Ella",6, 60123);oos1.writeObject(p1);oos1.flush();Person p2 = (Person) ois1.readObject();System.out.println(p2);ois1.close();
- 其他流的使用
- 了解:數據流 DataInputStream DataOutputStream
- 了解:標準的輸入流 System.in 標準的輸出流 System.out
- 了解:打印流:PrintStream PrintWriter
- 安裝第三方jar包的方法