Java——IO總結2

 字節數組流ByteArrayInputStream和ByteArrayOutputStream

經常用在需要流和數組之間轉化

FileInputStream是把文件當做數據源。ByteArrayInputStream則是把內存中的”某個字節數組對象”當做數據源。

import java.io.ByteArrayInputStream;
import java.io.IOException;
 
public class TestByteArray {
    public static void main(String[] args) {
        //將字符串轉變成字節數組
        byte[] b = "abcdefg".getBytes();
        test(b);
    }
    public static void test(byte[] b) {
        ByteArrayInputStream bais = null;
        StringBuilder sb = new StringBuilder();
        int temp = 0;
        //用於保存讀取的字節數
        int num = 0; 
        try {
            //該構造方法的參數是一個字節數組,這個字節數組就是數據源
            bais = new ByteArrayInputStream(b);
            while ((temp = bais.read()) != -1) {
                sb.append((char) temp);
                num++;
            }
            System.out.println(sb);
            System.out.println("讀取的字節數:" + num);
        } finally {
            try {
                if (bais != null) {
                    bais.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


數據流DataInputStream和DataOutputStream

     數據流將“基本數據類型與字符串類型”作爲數據源,從而允許程序以與機器無關的方式從底層輸入輸出流中操作Java基本數據類型與字符串類型。

public class TestDataStream {
    public static void main(String[] args) {
        DataOutputStream dos = null;
        DataInputStream dis = null;
        FileOutputStream fos = null;
        FileInputStream  fis = null;
        try {
            fos = new FileOutputStream("D:/data.txt");
            fis = new FileInputStream("D:/data.txt");
            //使用數據流對緩衝流進行包裝,新增緩衝功能
            dos = new DataOutputStream(new BufferedOutputStream(fos));
            dis = new DataInputStream(new BufferedInputStream(fis));
            //將如下數據寫入到文件中
            dos.writeChar('a');
            dos.writeInt(10);
            dos.writeDouble(Math.random());
            dos.writeBoolean(true);
            dos.writeUTF("北京尚學堂");
            //手動刷新緩衝區:將流中數據寫入到文件中
            dos.flush();
            //直接讀取數據:讀取的順序要與寫入的順序一致,否則不能正確讀取數據。
            System.out.println("char: " + dis.readChar());
            System.out.println("int: " + dis.readInt());
            System.out.println("double: " + dis.readDouble());
            System.out.println("boolean: " + dis.readBoolean());
            System.out.println("String: " + dis.readUTF());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(dos!=null){
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(dis!=null){
                    dis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fos!=null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fis!=null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

對象流

如果要對某個對象進行讀寫操作,我們需要學習一對新的處理流:ObjectInputStream/ObjectOutputStream。

      ObjectInputStream/ObjectOutputStream是以“對象”爲數據源,但是必須將傳輸的對象進行序列化與反序列化操作。

注:序列化實體類實現序列化接口時

serialVersionUID適用於Java的序列化機制。簡單來說,Java的序列化機制是通過判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVersionUID進行比較,如果相同就認爲是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常,即是InvalidCastException。
public class TestObjectStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        write();
        read();
    }
    /**使用對象輸出流將數據寫入文件*/
    public static void write(){
        // 創建Object輸出流,幷包裝緩衝流,增加緩衝功能
        OutputStream os = null;
        BufferedOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            os = new FileOutputStream(new File("d:/bjsxt.txt"));
            bos = new BufferedOutputStream(os);
            oos = new ObjectOutputStream(bos);
            // 使用Object輸出流
            //對象流也可以對基本數據類型進行讀寫操作
            oos.writeInt(12);
            oos.writeDouble(3.14);
            oos.writeChar('A');
            oos.writeBoolean(true);
            //對象流能夠對對象數據類型進行讀寫操作
            //Date是系統提供的類,已經實現了序列化接口
            //如果是自定義類,則需要自己實現序列化接口
            oos.writeObject(new Date());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //關閉輸出流
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**使用對象輸入流將數據讀入程序*/
    public static void read() {
        // 創建Object輸入流
        InputStream is = null;
        BufferedInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            is = new FileInputStream(new File("d:/bjsxt.txt"));
            bis = new BufferedInputStream(is);
            ois = new ObjectInputStream(bis);
            // 使用Object輸入流按照寫入順序讀取
            System.out.println(ois.readInt());
            System.out.println(ois.readDouble());
            System.out.println(ois.readChar());
            System.out.println(ois.readBoolean());
            System.out.println(ois.readObject().toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 關閉Object輸入流
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

轉換流

      InputStreamReader/OutputStreamWriter用來實現將字節流轉化成字符流。

      System.in是字節流對象,代表鍵盤的輸入,如果我們想按行接收用戶的輸入時,就必須用到緩衝字符流BufferedReader特有的方法readLine(),但是經過觀察會發現在創建BufferedReader的構造方法的參數必須是一個Reader對象,這時候我們的轉換流。

      而System.out也是字節流對象,代表輸出到顯示器,按行讀取用戶的輸入後,並且要將讀取的一行字符串直接顯示到控制檯,就需要用到字符流的write(String str)方法,所以我們要使用OutputStreamWriter將字節流轉化爲字符流。

使用InputStreamReader接收用戶的輸入,並輸出到控制檯

public class TestConvertStream {
    public static void main(String[] args) {
        // 創建字符輸入和輸出流:使用轉換流將字節流轉換成字符流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            // 使用字符輸入和輸出流
            String str = br.readLine();
            // 一直讀取,直到用戶輸入了exit爲止
            while (!"exit".equals(str)) {
                // 寫到控制檯
                bw.write(str);
                bw.newLine();// 寫一行後換行
                bw.flush();// 手動刷新
                // 再讀一行
                str = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 關閉字符輸入和輸出流
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章