Java中的IO流 - 入門篇
前言
大家好啊,我是湯圓,今天給大家帶來的是《Java中的IO流-入門篇》,希望對大家有幫助,謝謝
由於Java的IO類有很多,這就導致我剛開始學的時候,感覺很亂,每次用到都是上網搜,結果每次用完就忘;
後來沉下心去看書學習,才明白都是有規律的;
這裡先做個簡單的介紹,作為入門級教程,後面還有很多要學習的,有空再整理吧。
簡介
檔案IO流,主要有兩種方式
-
位元組流:基於普通的Java物件,僅適用於Java程式之間的讀寫
-
字元流:基於普通的文字字串,不僅適用於Java程式之間的讀寫,也適用於Java程式和其他語言程式之間的讀寫
本例中用到的相關類如下:
所有的讀寫操作都是針對記憶體而言的,因為程式就是執行在記憶體中
讀操作就是從磁碟檔案或網路流讀到記憶體,對於記憶體而言就是Input
寫操作就是從記憶體寫到磁碟檔案或網路流,對於記憶體而言就是Output
下面分別介紹這兩種方式
位元組流:基於普通的Java物件
位元組流的讀和寫都是基於Java程式而言,比如在一個機器上的Java程式寫入一個物件到檔案,然後傳輸到另一個機器上的Java程式去讀取檔案中的物件
寫入Java物件時,會先將Java物件序列化(物件轉為位元組),然後寫入
讀取Java物件時,會先將Java物件反序列化(位元組轉為物件),然後讀取
寫物件
將物件寫入到檔案中,需要先把物件序列化,然後再把序列化後的位元組寫入到檔案中;
序列化就是將物件的屬性資訊轉為一系列位元組(不包括transient 型別的屬性,下面會介紹)
大概流程如下所示:
讀物件
將物件從檔案中讀出來,需要先反序列化,然後再轉為對應的Java物件,並恢復物件屬性值
反序列化就是將一系列位元組轉為真實的物件例項(不包括transient型別的屬性)
大概流程如下所示:
transient
該修飾符 字面意思是瞬時的,短暫的
用在物件的屬性上,就表示這個屬性是暫時有效的,等序列化的時候會失效
在反序列化的時候,這個屬性就會為null(如果屬性是物件引用)或基礎型別的預設值(如果屬性是基礎型別)
比如密碼等比較隱私的屬性,我們就可以設定為transient
程式碼
public class ObjectIoDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InnerObject object1 = new InnerObject(10);
String filename = "object.bin";
writeObjectFun(filename, object1);
InnerObject objectReturn = (InnerObject) readObjectFun(filename);
System.out.println(objectReturn);
}
// 寫物件 到指定檔案
public static void writeObjectFun(String filename, Object o) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(filename);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(o);
// 關閉流,fileOutputStream會一併關閉
objectOutputStream.close();
}
// 讀物件 從指定檔案
public static Object readObjectFun(String filename) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream(filename);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object o = objectInputStream.readObject();
// 關閉流,fileInputStream會一併關閉
objectInputStream.close();
return o;
}
}
class InnerObject implements Serializable{
@Override
public String toString() {
return "InnerObject{" +
"num=" + num +
'}';
}
public InnerObject(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
private int num;
}
如果要寫入的Java物件沒有序列化,則會報錯如下
Exception in thread "main" java.io.NotSerializableException: com.jalon.basic.io.InnerObject
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.jalon.basic.io.ObjectIoDemo.writeObjectFun(ObjectIoDemo.java:28)
at com.jalon.basic.io.ObjectIoDemo.main(ObjectIoDemo.java:19)
字元流:基於普通文字字串
字元流寫入到檔案中的資料,是作為通用文字資料來處理的,這樣Java程式和其他程式都可以去讀寫這個檔案
寫文字
大致流程如下:
讀文字
大致流程如下:
BufferedReader和BufferedWriter的作用
為什麼要用緩衝區呢?直接用FileReader和FileWriter不也可以嗎?
如果直接用FileWriter
和FileReader
是可以執行,只不過效率會比較低,因為每一次的讀寫都是針對磁碟操作的;
而BufferedWriter
和BufferedReader
這兩個緩衝區可以減少磁碟的讀寫次數;
BufferedReader
:程式可以從磁碟一次性讀很多資料到緩衝區,再從緩衝區一次次讀,等緩衝區為空時再去磁碟讀;
BufferedWriter
:程式可以寫多次到緩衝區,等快取區滿了再一次性寫入到磁碟中
程式碼
public class TextIoDemo {
public static void main(String[] args) throws IOException {
String filename = "string.txt";
writeString(filename, "hello world");
String res = readString(filename);
System.out.println(res);
}
// 寫字串到指定檔案
public static void writeString(String filename, String content) throws IOException {
FileWriter fileWriter = new FileWriter(filename);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(content);
bufferedWriter.close();
}
// 從指定檔案讀取字串
public static String readString(String filename) throws IOException {
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line=bufferedReader.readLine())!=null){
stringBuilder.append(line);
}
bufferedReader.close();
return stringBuilder.toString();
}
}
總結
IO流分為位元組流和字元流
如果讀寫兩邊都是Java程式,則推薦用位元組流,序列化和反序列化很方便
如果一邊是Java程式,另一邊是其他語言的程式,則推薦用字元流,讀寫的內容都是文字格式,方便解析
上面只是列出了個別讀寫類,Java中讀寫類還有很多,大家感興趣的可以去java.io下檢視
參考
-
《Head First Java》(第二版)
-
《Java 核心技術卷一》(第十版)
-
《Java 程式設計思想》(第四版)
後記
最後,感謝大家的觀看,