Java IO流詳解(四)

來源:互聯網
上載者:User

標籤:java-io   java流   流操作   stream   io   

Serializable序列化
1 對象的序列化

    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 serialTest {        public static void main(String[] args) {            String path = "D:\\Program Files (x86)\\ADT\\workspace\\JavaIO\\demoTest.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 還原序列化

package com.yin.serialize;import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;public class serialTestFan {    public static void main(String[] args) {        String path = "D:\\Program Files (x86)\\ADT\\workspace\\JavaIO\\demoTest.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);            Person p2 = (Person)ois.readObject();            System.out.println(p2);//            Person p3 = (Person)ois.readObject();//            if (p3 == null) {//              System.out.print("p3==null");//          }else {//              System.out.println(p3);//          }            //拋死你,煩煩煩~!!!        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } finally {            try {                //還是要記得關閉下流                ois.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

結果:

對應於上面序列化時寫入的對象。
值得注意的是,如果把注釋的代碼去掉注釋,則出現EOFException異常,也就是說讀取完資料對象之後,不允許往下讀取了。只能有多少對象資料讀取多少對象。

3 管道流
線程的通訊

package com.yin.serialize;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類,操作原理都一樣

4 DataOutputStream和DataInputStream類
基礎資料型別 (Elementary Data Type)的寫入

package com.yin.serialize;import java.io.DataOutputStream;import java.io.FileOutputStream;import java.io.IOException;public class DataStreamTest {    public static void main(String[] args) {        String path = "D:\\Program Files (x86)\\ADT\\workspace\\JavaIO\\demoTest.txt";        DataOutputStream d = null;            try {                //此處需要傳入一個OutputStream類的對象                d = new DataOutputStream(new FileOutputStream(path));                //開始寫入基礎資料型別 (Elementary Data Type)                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 基礎資料型別 (Elementary Data Type)的讀取

import java.io.DataInputStream;import java.io.FileInputStream;import java.io.IOException;public class DataReadTest {    public static void main(String[] args) {        String path = "D:\\Program Files (x86)\\ADT\\workspace\\JavaIO\\demoTest.txt";        DataInputStream d = null;            try {                d = new DataInputStream(new FileInputStream(path));                //按儲存順序讀取基礎資料型別 (Elementary Data Type)                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();                }            }    }}

結果:

這個結果與上面的資料寫入順序一致。也就是說讀取資料和寫入資料一致!!注意!否則會發生資料的列印錯誤!
參考 :http://www.cnblogs.com/nerxious/archive/2012/12/17/2822365.html

源碼下載

Java IO流詳解(四)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.