1. 程式人生 > >I/O操做總結(四))

I/O操做總結(四))

zab 方法 字符 add i/o spa 我們 ppr bsp

前面已經把java io的主要操作講完了

這一節我們來說說關於java io的其他內容

Serializable序列化

實例1:對象的序列化

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import java.io.File; import java.io.FileOutputStream; import java.io.IOException;
import java.io.ObjectOutputStream; import java.io.Serializable; @SuppressWarnings("serial") //一個類要想實現序列化則必須實現Serializable接口 class Person implements Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age;
} public String toString() { return "Name:" + this.name + ", Age:" + this.age; } } public class Demo { public static void main(String[] args) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator +
"demo.txt"; Person p1 = new Person("zhangsan",12); Person p2 = new Person("lisi",14); //此處創建文件寫入流的引用是要給ObjectOutputStream的構造函數玩兒 FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(path); oos = new ObjectOutputStream(fos); //這裏可以寫入對象,也可以寫入其他類型數據 oos.writeObject(p1); oos.writeObject(p2); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

所謂對象序列化就是把一個對象進行持久化存儲,方便保留其屬性

通俗點說,等於把一個對象從堆內存裏邊揪出來放到硬盤上

當然,如果你開心,你可以序列化其他東西,包括數組,基本數據類型等等

來看看內容,神馬玩意兒這是……

技術分享

實例2:對象的反序列化

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class Demo { public static void main(String[] args) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; //好吧,這裏代碼寫得著實有點長了,還要拋異常什麽的 //如果你也看的煩,那就在主方法上拋吧,構造方法裏用匿名對象就好了 //什麽?別告訴我你不知道匿名對象 FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream(path); ois = new ObjectInputStream(fis); //這裏返回的其實是一個Object類對象 //因為我們已知它是個Person類對象 //所以,就地把它給向下轉型了 Person p = (Person)ois.readObject(); System.out.println(p); //拋死你,煩煩煩~!!! } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { //還是要記得關閉下流 ois.close(); } catch (IOException e) { e.printStackTrace(); } } } }

你看,我們把一個對象存放在硬盤上是為了方便日後使用

現在用得著它了,自然得拿出來

技術分享

管道流

實例3:線程的通信

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; //實現Runnable接口,實現一個讀的線程 class Read implements Runnable { private PipedInputStream in; //將需要讀的管道流傳入到構造函數中 public Read(PipedInputStream in) { this.in = in; } //實現讀這一線程 public void run() { try { byte[] buf = new byte[1024]; int temp = 0; //循環讀取 //read是一個阻塞方法,需要拋異常 //此處把打印流的代碼也加入進來 //是因為如果沒有讀取到數據,那麽打印的代碼也無效 while((temp = in.read(buf)) != -1) { String str = new String(buf,0,temp); System.out.println(str); } } catch (IOException e) { //其實這裏應拋出一個自定義異常的 //暫時我還沒弄清楚 e.printStackTrace(); } finally { try { //我已經拋火了,這只是為了提醒自己異常很重要 in.close(); } catch (IOException e) { e.printStackTrace(); } } } } //這裏實現一個寫的類 class Write implements Runnable { private PipedOutputStream out; //將管道輸入流傳進來 public Write(PipedOutputStream out) { this.out = out; } public void run() { try { //這裏開始寫出數據 out.write("管道輸出".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { //其實應該可以把這個關閉方法寫到上面那個try裏邊 //但是這樣感覺怪怪的,邏輯不大對 out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public class Demo { public static void main(String[] args) { PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); try { //連接管道 in.connect(out); //創建對象,開啟線程 //此處同樣放進try...catch裏面 //因為如果沒有鏈接管道,下面操作無意義 Read r = new Read(in); Write w = new Write(out); //把已經實現好run方法的對象放入線程中執行 new Thread(r).start(); new Thread(w).start(); } catch (IOException e) { e.printStackTrace(); } } }

好吧,廢了那麽大勁兒,就打印了這麽一句話,異常拋棄來很煩,為了註重細節……

技術分享

管道流也許很難理解,其實非也

我們知道,字節流和字符流都需要數組來進行流的中轉

而管道流則直接串聯兩條流,一邊發送數據,一邊接收

然而,同時通信的的兩種狀態,如何才能確定發送和接收的一致性呢

那麽,就需要用到線程,無論是接收方還是發送方先執行

總會造成一個線程的阻塞狀態,從而等待另一方的數據傳過來

總體而言,管道流的目的,也就是為了線程通信

此外,還有PipedReader和PipedWriter類,操作原理都一樣,這裏就不再贅述了

DataOutputStream和DataInputStream類

實例4:基本數據類型的寫入

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class Demo { public static void main(String[] args) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; DataOutputStream d = null; try { //此處需要傳入一個OutputStream類的對象 d = new DataOutputStream(new FileOutputStream(path)); //開始寫入基本數據類型 d.writeInt(12); d.writeBoolean(true); d.writeDouble(12.2223); d.writeChar(97); //刷新流 d.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { d.close(); } catch (IOException e) { e.printStackTrace(); } } } }

此處我們並不能直觀看懂內容,因為它采用字節流的方式操作,而不是字符流

我們只需要知道,此程序已經將基本數據類型寫入到硬盤即可

技術分享

實例5:基本數據類型的讀取

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class Demo { public static void main(String[] args) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; DataInputStream d = null; try { d = new DataInputStream(new FileInputStream(path)); //按存儲順序讀取基本數據類型 System.out.println(d.readInt()); System.out.println(d.readBoolean()); System.out.println(d.readDouble()); System.out.println(d.readChar()); } catch (IOException e) { e.printStackTrace(); } finally { try { d.close(); } catch (IOException e) { e.printStackTrace(); } } } }

這裏要註意的是,一定要按照寫入順序讀取,否則會發生數據的打印錯誤

技術分享

I/O操做總結(四))