IO

IO文件讀寫

輸入流 輸出流
字節(jié)流 字節(jié)輸入流<br />InputStream 字節(jié)輸出流<br />OutputStream
字符流 字符輸入流<br />Reader 字符輸出流<br />Writer

字節(jié)流

字節(jié)輸出流

java.io.OutputStream:這個(gè)抽象類是表示字節(jié)輸出流的所有類的超類肮雨。

方法:

  • void close() :關(guān)閉此輸出流并釋放與此流相關(guān)聯(lián)的任何系統(tǒng)資源最易。

  • void flush():刷新此輸出流并強(qiáng)制任何緩沖的輸出字節(jié)被寫出揍移。

  • void write(byte[] b):將 b.length字節(jié)從指定的字節(jié)數(shù)組寫入此輸出流摆出。

  • void write(byte[] b, int off, int len):從指定的字節(jié)數(shù)組寫入 len個(gè)字節(jié)臀规,從偏移 off開始輸出到此輸出流。

  • abstract void write(int b):將指定的字節(jié)寫入此輸出流昧辽。

FileOutputStream類

java.io.FileOutputStream extends OutputStream把內(nèi)存中的數(shù)據(jù)寫入到硬盤的文件中

構(gòu)造方法:

  • FileOutputStream(String name):創(chuàng)建文件輸出流以指定的名稱寫入文件瘪校。
  • FileOutputStream(File file):創(chuàng)建文件輸出流以寫入由指定的 File對(duì)象表示的文件。

構(gòu)造方法的作用:

  1. 創(chuàng)建一個(gè)FileOutputStream對(duì)象
  2. 根據(jù)構(gòu)造方法中傳遞的文件/文件路徑九孩,創(chuàng)建一個(gè)空的文件
  3. 把FileOutputStream對(duì)象指向創(chuàng)建好的文件

寫入數(shù)據(jù)的原理(內(nèi)存 --> 硬盤):

java程序 --》 JVM(java虛擬機(jī)) --》OS(操作系統(tǒng)) --》OS調(diào)用寫數(shù)據(jù)的方法 --》 把數(shù)據(jù)寫入到文件中

案例:

package com.jz.demo;

import java.io.FileOutputStream;
import java.io.IOException;

/*
    字節(jié)輸出流的使用步驟:
        1.創(chuàng)建一個(gè)FileOutputStream對(duì)象先馆,構(gòu)造方法中傳遞寫入數(shù)據(jù)的目的地。
        2.調(diào)用FileOutputStream對(duì)象中的方法write躺彬,把數(shù)據(jù)寫入到文件中煤墙。
        3.釋放資源。
 */
public class OutputStreamTest01 {
    public static void main(String[] args) throws IOException {
        // 1.創(chuàng)建一個(gè)FileOutputStream對(duì)象宪拥,構(gòu)造方法中傳遞寫入數(shù)據(jù)的目的地仿野。
        FileOutputStream fos = new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\a.txt");
        // 2.調(diào)用FileOutputStream對(duì)象中的方法write,把數(shù)據(jù)寫入到文件中她君。
        fos.write(98);
        // 3.釋放資源
        fos.close();
    }
}

package com.jz.demo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

/*
    一次寫多個(gè)字節(jié)的方法:
        public void write(byte[] b):將b.length字節(jié)從指定的字節(jié)數(shù)組寫入此輸出流
        public void write(byte[] b, int off, int len):從指定的字節(jié)數(shù)組寫入 len字節(jié)脚作,從偏移量 off開始輸出到此輸出流。
 */
public class OutputStreamTest02 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\b.txt");

        fos.write(49);
        fos.write(48);
        fos.write(48);

        /*
            public void write(byte[] b):將b.length字節(jié)從指定的字節(jié)數(shù)組寫入此輸出流
            一次寫多個(gè)字節(jié):
                如果寫的第一個(gè)字節(jié)是正數(shù)(0-127)缔刹,那么顯示的時(shí)候會(huì)查詢ASCII表
                如果寫的第一個(gè)字節(jié)是負(fù)數(shù)球涛,那第一個(gè)字節(jié)會(huì)和第二個(gè)字節(jié),兩個(gè)字節(jié)組成一個(gè)中文顯示校镐,查詢系統(tǒng)默認(rèn)碼表(GBK)
         */
        byte[] bytes = {65, 66, 67, 68}; // ABCD
        // byte[] bytes = {-65, -66, -67, 68, 69}; // 烤紻E
        fos.write(bytes);

        /*
            public void write(byte[] b, int off, int len):從指定的字節(jié)數(shù)組寫入 len字節(jié)亿扁,從偏移量 off開始輸出到此輸出流。
            把字節(jié)數(shù)組的一部分寫入文件中
                int off:開始的索引
                int length:寫幾個(gè)字節(jié)
        */
        fos.write(bytes, 1, 2); // BC

        /*
            寫入字符串方法:可以使用String類中的方法把字符串鸟廓,轉(zhuǎn)換為字節(jié)數(shù)組
                byte[] getBytes() 把字符串轉(zhuǎn)換為字節(jié)數(shù)組
         */
        byte[] bytes1 = "你好".getBytes();
        System.out.println(Arrays.toString(bytes1)); // [-28, -67, -96, -27, -91, -67]
        fos.write(bytes1);

        fos.close();
    }
}

數(shù)據(jù)追加續(xù)寫:

package com.jz.demo;

import java.io.FileOutputStream;
import java.io.IOException;

/*
    FileOutputStream(File file, boolean append):創(chuàng)建文件輸出流以寫入由指定的 File對(duì)象表示的文件魏烫。
    FileOutputStream(String name, boolean append):創(chuàng)建文件輸出流以指定的名稱寫入文件。
 */
public class OutputStreamTest03 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\c.txt", true);
        for (int i = 0; i < 10; i++) {
            fos.write("你好".getBytes());
            fos.write("\r\n".getBytes());
        }
        fos.close();
    }
}

字節(jié)輸入流

java.io.InputStream

方法:

  • public void close():關(guān)閉此輸入流并釋放與流相關(guān)聯(lián)的任何系統(tǒng)資源肝箱。
  • public abstract int read():從該輸入流讀取下一個(gè)數(shù)據(jù)字節(jié)哄褒。
  • public int read(byte[] b):從該輸入流讀取最多 byte.length個(gè)字節(jié)的數(shù)據(jù)到字節(jié)數(shù)組。

FileInputStream類

java.io.FileInputStream extends InputStream

FileInputStream:文件字節(jié)輸入流

作用:把硬盤文件中的數(shù)據(jù)煌张,讀取到內(nèi)存中使用

構(gòu)造方法:

  • FileInputStream(String name)

    String name:文件的路徑

  • FileInputStream(File file)

    File file:文件

構(gòu)造方法的作用:

  1. 創(chuàng)建一個(gè)FileInputStream對(duì)象
  2. 把FileInputStream對(duì)象指定構(gòu)造方法中要讀取的文件

讀取數(shù)據(jù)原理(硬盤-->內(nèi)存)

java程序 --> JVM --> OS --> OS讀取數(shù)據(jù)的方法 -->讀取文件

package com.jz.demo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("c:\\1.png");
        FileOutputStream fos = new FileOutputStream("d:\\1.png");
        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!= -1){
            fos.write(bytes, 0 , len);
        }
//        while((len = fis.read()) != -1){
//            fos.write(len);
//        }
        fos.close();
        fis.close();
    }
}

字符流

使用字節(jié)流在讀取中文字符時(shí)玉雾,可能出現(xiàn)顯示亂碼問題多柑。

字符輸入流

java.io.Reader 抽象類是表示用于讀取字符流的所有類的超類订框。

共性方法:

  • public void close() 釋放資源
  • public int read() 從輸入流讀取一個(gè)字符
  • public int read(char[] cbuf) 從輸入流中讀取一些字符懂版,并將它們存儲(chǔ)到字符數(shù)組cbuf中。

public class FileReader extends InputStreamReader

package com.jz.reader;

import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class ReaderDemo01 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\c.txt");
        int len = 0;
        char[] cs = new char[1024];
        while((len = fr.read(cs)) != -1){
            System.out.println(len);
            System.out.println(new String(cs, 0, len));
        }
        fr.close();
    }
}

字符輸出流

java.io.Writer 字符輸出流档玻,所有字符輸出流的最頂層的父類怀泊,是一個(gè)抽象類。

public class FileWriter extends OutputStreamWriter extends Writer

package com.jz.writer;

import java.io.FileWriter;
import java.io.IOException;

public class WriterDemo01 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\d.txt");
        fw.write(97); // 把數(shù)據(jù)寫入到內(nèi)存緩沖區(qū)(字符轉(zhuǎn)換為字節(jié)的過程)
        fw.flush(); // 把內(nèi)存緩沖區(qū)中的數(shù)據(jù)误趴,刷新到文件中
        fw.close(); // 釋放資源之前先把內(nèi)存緩沖區(qū)中的數(shù)據(jù)刷新到文件中
    }
}

由于關(guān)閉(close) 和 刷新(flush)都可以將內(nèi)存緩沖區(qū)中的數(shù)據(jù)霹琼,刷新到文件中

flush方法和close方法的區(qū)別:

  • flush 刷新緩沖區(qū),流對(duì)象可以繼續(xù)使用
  • close 先刷新緩沖區(qū),然后通知系統(tǒng)釋放資源枣申。流對(duì)象不能再被使用
package com.jz.writer;

import java.io.FileWriter;
import java.io.IOException;

/*
    字符輸出流寫數(shù)據(jù)的其他方法
 */
public class WriterDemo01 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\d.txt");
        char[] cs = {'a', 'b', 'c', 'd'};
        fw.write(cs);//  void write(char[] cbuf) 寫入字符數(shù)組

        fw.write(cs, 1, 2); // 寫入數(shù)組的一部分?jǐn)?shù)據(jù)

        fw.write("嘿嘿嘿"); // 直接寫入字符串

        fw.write("嘿嘿嘿呼呼呼", 3, 3); //  寫入一部分字符串

        fw.flush();
        fw.close();
    }
}

續(xù)寫和換行:

package com.jz.writer;

import java.io.FileWriter;
import java.io.IOException;

/*
    字符輸出流寫數(shù)據(jù)的其他方法
 */
public class WriterDemo01 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\CODE\\JAVA\\IDEA\\javabase\\io\\d.txt", true);
        
        fw.write("\r\n"); // 回車換行

        char[] cs = {'a', 'b', 'c', 'd'};
        fw.write(cs);//  void write(char[] cbuf) 寫入字符數(shù)組

        fw.write(cs, 1, 2); // 寫入數(shù)組的一部分?jǐn)?shù)據(jù)

        fw.write("嘿嘿嘿"); // 直接寫入字符串

        fw.write("嘿嘿嘿呼呼呼", 3, 3); //  寫入一部分字符串

        fw.flush();
        fw.close();
    }
}

緩沖流

100.png

字節(jié)緩沖流

字節(jié)緩沖輸出流

java.io.BufferedOutputStream extends OutputStream

package com.jz.io;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedOutputStreamDemo01 {

    public static void main(String[] args) throws IOException {
        // 1.創(chuàng)建FileOutputStream對(duì)象
        FileOutputStream fos = new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\a.txt");
        // 2.創(chuàng)建BufferedOutputStream對(duì)象
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        // 3.使用BufferedOutputStream對(duì)象中的write方法售葡,把數(shù)據(jù)寫入內(nèi)存緩沖區(qū)
        bos.write("我把數(shù)據(jù)寫入緩沖qv".getBytes());
        bos.flush();
        bos.close();
    }
}

字節(jié)緩沖輸入流

java.io.BufferedInputStream extends InputStream

package com.jz.io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        //1.創(chuàng)建FileInputStream對(duì)象
        FileInputStream fis = new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\a.txt");
        //2.創(chuàng)建BufferedInputStream對(duì)象
        BufferedInputStream bis = new BufferedInputStream(fis);
        //3.使用BufferedInputStream對(duì)象中的read,讀取文件
        // int read()從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)
        /*int len = 0; // 記錄每次讀取到的字節(jié)
        while((len = bis.read()) != -1){
            System.out.println((char)len);
        }*/

        // int read(byte[] b)從輸入流中讀取一定數(shù)量的字節(jié)忠藤,并將其存儲(chǔ)到緩沖區(qū)數(shù)組b中
        byte[] bytes = new byte[1024];
        int len = 0; //記錄每次讀取的有效字節(jié)個(gè)數(shù)
        while((len = bis.read(bytes)) != -1){
            System.out.println(new String(bytes, 0, len));
        }
        bis.close();
    }
}

文件復(fù)制:

package com.jz.io;

import java.io.*;

public class CopyFile {
    public static void main(String[] args) throws IOException {
        long s = System.currentTimeMillis();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\1.png"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\1.png"));
        /*int len = 0;
        while((len = bis.read()) != -1){
            bos.write(len);
        }*/
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = bis.read(bytes)) != -1){
            bos.write(bytes);
        }

        bos.close();
        bis.close();
        long e = System.currentTimeMillis();
        System.out.println("共用了: "+(e-s)+"毫秒");
    }
}

字符緩沖流

字符緩沖輸出流

java.io.BufferedWriter extends Writer

package com.jz.io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterDemo01 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\CODE\\JAVA\\IDEA\\IO\\b.txt"));
        for (int i = 0; i < 10; i++) {
            bw.write("嘿嘿嘿");
            //bw.write("\r\n");
            bw.newLine();
        }
        bw.flush();
        bw.close();
        System.out.println();
    }
}

字符緩沖輸入流

java.io.BufferedReader extends Reader

package com.jz.io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderDemo01 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("D:\\CODE\\JAVA\\IDEA\\IO\\b.txt"));
        /*String line = br.readLine();// 一次讀取一行數(shù)據(jù)
        System.out.println(line);*/

        String line = "";
        while((line = br.readLine()) != null){ // 讀取到null結(jié)束
            System.out.println(line);
        }

        br.close();
    }
}

文件內(nèi)容排序:

package com.jz.io;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) throws IOException {
        Map<String, String> map = new HashMap<>();
        BufferedReader br = new BufferedReader(new FileReader("D:\\CODE\\JAVA\\IDEA\\IO\\b.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\CODE\\JAVA\\IDEA\\IO\\c.txt"));

        String line = "";
        while((line = br.readLine()) != null){
            String[] split = line.split("\\.");
            map.put(split[0], split[1]);
        }

        Set<Map.Entry<String, String>> set = map.entrySet();
        for (Map.Entry<String, String> entry : set) {
            bw.write(entry.getKey()+"."+entry.getValue());
            bw.newLine();
        }

        bw.close();
        br.close();
    }
}

轉(zhuǎn)換流

指定編碼表

轉(zhuǎn)換流中的輸出流

java.io.OutputStreamWriter extends Writer

OutputStreamWriter:字符流通向字節(jié)流的橋梁挟伙,可使用指定的 charset 將要寫入流中的字符編碼稱字節(jié)。

構(gòu)造方法:

  • OutputStreamWriter(OutputStream out)創(chuàng)建使用默認(rèn)字符編碼的 OutputStreamWriter
  • OutputStreamWriter(OutputStream out, String charsetName) 創(chuàng)建使用指定字符集的 OutputStreamWriter模孩。
package com.jz.io;

import java.io.*;

public class OutputStreamWriterDemo01 {
    public static void main(String[] args) throws IOException {
//        write_utf_8();
        write_gbk();
    }

    private static void write_gbk() throws IOException {
        // 創(chuàng)建OutputStreamWriter對(duì)象尖阔,構(gòu)造方法中傳遞字節(jié)輸出流和指定的編碼表名稱
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\gbk.txt"), "gbk");
        // 使用OutputStreamWriter對(duì)象中的方法writer,把字符轉(zhuǎn)換為字節(jié)存儲(chǔ)緩沖區(qū)中(編碼)
        osw.write("你好");
        // 使用OutputStreamWriter對(duì)象中的方法flush,把內(nèi)存緩沖區(qū)中的字節(jié)刷洗到文件中(使用字節(jié)流寫字節(jié)的過程)
        osw.flush();
        osw.close();
    }

    /*
        使用轉(zhuǎn)換流OutputStreamWriter寫UTF-8格式的文件
     */
    private static void write_utf_8() throws IOException {
        // 創(chuàng)建OutputStreamWriter對(duì)象,構(gòu)造方法中傳遞字節(jié)輸出流和指定的編碼表名稱
//        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\utf_8.txt"), "utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\utf_8.txt")); // 不指定編碼默認(rèn)utf-8
        // 使用OutputStreamWriter對(duì)象中的方法writer,把字符轉(zhuǎn)換為字節(jié)存儲(chǔ)緩沖區(qū)中(編碼)
        osw.write("你好");
        // 使用OutputStreamWriter對(duì)象中的方法flush,把內(nèi)存緩沖區(qū)中的字節(jié)刷洗到文件中(使用字節(jié)流寫字節(jié)的過程)
        osw.flush();
        osw.close();
    }
}

轉(zhuǎn)換流中的輸入流

java.io.InputStreamReader extends Reader

InputStreamReader:字節(jié)流通向字符流的橋梁榨咐,它使用指定的 charset 讀取字節(jié)并將其解碼為字符介却。(解碼:把看不懂的變成能看懂的)

構(gòu)造方法:

  • InputStreamReader(InputStream in) 創(chuàng)建一個(gè)使用默認(rèn)字符集的 InputStreamReader
  • InputStreamReader(InputStream in, String charsetName)創(chuàng)建使用指定字符集的 InputStreamReader

注意事項(xiàng):

構(gòu)造方法中指定的編碼表名稱要和文件的編碼相同,否則會(huì)出現(xiàn)亂碼

package com.jz.io;


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderDemo01 {
    public static void main(String[] args) throws IOException {
//        read_utf_8();
        read_gbk();
    }

    /*
         使用InputStreamReader讀取gbk格式的文件
     */
    private static void read_gbk() throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\gbk.txt"), "gbk");
        int len = 0;
        while((len = isr.read()) != -1){
            System.out.println((char)len);
        }
        isr.close();
    }

    /*
        使用InputStreamReader讀取UTF-8格式的文件
     */
    private static void read_utf_8() throws IOException {
//        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\utf_8.txt"), "utf-8");
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\utf_8.txt"));
        // 使用InputStreamReader對(duì)象中的方法read讀取文件
        int len = 0;
        while((len = isr.read()) != -1){
            System.out.println((char)len);
        }
        isr.close();
    }

}

案例:轉(zhuǎn)換文件編碼

package com.jz.io;

import java.io.*;

public class Test2 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\gbk.txt"), "gbk");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\utf8.txt"), "utf-8");
        int len = 0;
        while((len = isr.read()) != -1){
            osw.write(len);
        }
        osw.flush();
        osw.close();
        isr.close();
    }
}

序列化

101.png

對(duì)象序列化流

java.io.ObjectOutputStream extends OutputStream

作用:把對(duì)象以流的方式寫入到文件中保存

構(gòu)造方法:

  • ObjectOutputStream(OutputStream out) 創(chuàng)建寫入指定 OutputStream 的 ObjectOutputStream.

特有的成員方法:

void writeObject(Object obj) 將指定的對(duì)象寫入 ObjectOutputStream

序列化異常:

Exception in thread "main" java.io.NotSerializableException 沒有序列化異常

package com.jz.objectStream;

import java.io.Serializable;

/*
    序列化和反序列化的時(shí)候祭芦,會(huì)拋出NotSerializableException沒后序列化異常
    類通過實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能筷笨。未實(shí)現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化憔鬼。
    Serializable接口也叫標(biāo)記型接口
 */
public class Person implements Serializable {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.jz.objectStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
        // 創(chuàng)建ObjectOutputStream對(duì)象龟劲,構(gòu)造方法中傳遞字節(jié)輸出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\person.txt"));
        // 使用ObjectOutputStream對(duì)象中的方法writeObject,把對(duì)象寫入文件中
        Person p = new Person("小明", 19);
        oos.writeObject(p);
        oos.flush();
        oos.close();
    }
}


對(duì)象反序列化流

java.io.ObjectInputStream extends InputStream

作用:把文件中保存的對(duì)象,以流的方式讀取出來使用

構(gòu)造方法:

  • ObjectInputStream(InputStream in) 創(chuàng)建從指定 InputStream 讀取的 ObjectInputStream

特有的成員方法:

  • Object readObject()ObjectInputStream 讀取對(duì)象

    聲明拋出了ClassNotFoundException異常

反序列化前提:

  1. 類必須實(shí)現(xiàn)Serializable
  2. 必須存在類對(duì)應(yīng)的class文件
package com.jz.objectStream;

import java.io.Serializable;

/*
    序列化和反序列化的時(shí)候轴或,會(huì)拋出NotSerializableException沒后序列化異常
    類通過實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能昌跌。未實(shí)現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化。
    Serializable接口也叫標(biāo)記型接口
 */
public class Person implements Serializable {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

package com.jz.objectStream;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStreamDemo01 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\person.txt"));
        Object o = ois.readObject();
        ois.close();
        System.out.println(o);
    }
}

static關(guān)鍵字:靜態(tài)關(guān)鍵字

? 靜態(tài)優(yōu)先于非靜態(tài)加載到內(nèi)存中(靜態(tài)優(yōu)先于對(duì)象進(jìn)入到內(nèi)存中)照雁,被static修飾的成員變量不能被初始化蚕愤,序列化的都是對(duì)象

transient關(guān)鍵字:瞬態(tài)關(guān)鍵字

? 被transient修飾的成員變量,不能被序列化 private transient int age;

反序列化操作:

當(dāng)JVM反序列化對(duì)象時(shí)饺蚊,能找到class文件萍诱,但是class文件在序列化對(duì)象之后發(fā)生了修改,那么反序列化操作也會(huì)失敗污呼,拋出一個(gè)InvalidClassException異常裕坊。

102.png

練習(xí):序列化集合

package com.jz.objectStream;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/*
    把多個(gè)對(duì)象存儲(chǔ)到集合中,對(duì)集合進(jìn)行序列化和反序列化
 */
public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 定義存儲(chǔ)Person對(duì)象的ArrayList集合
        List<Person> list = new ArrayList<>();
        // 向list集合中添加Person對(duì)象
        list.add(new Person("小明",18));
        list.add(new Person("小紅",20));
        list.add(new Person("小聰",10));
        // 創(chuàng)建序列化流ObjectOutputStream對(duì)象
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\CODE\\JAVA\\IDEA\\IO\\list.txt"));
        //使用ObjectOutputStream對(duì)象中的方法writeObject,對(duì)集合進(jìn)行序列化
        oos.writeObject(list);
        // 創(chuàng)建反序列化ObjectInputStream對(duì)象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\CODE\\JAVA\\IDEA\\IO\\list.txt"));
        // 使用ObjectInputStream對(duì)象中的方法readObject讀取文件中保存的集合
        Object o = ois.readObject();
        // 把Object類型的集合轉(zhuǎn)換為ArrayList類型
        ArrayList<Person> list2 = (ArrayList<Person>) o;
        for (Person person : list2) {
            System.out.println(person);
        }

        ois.close();
        oos.close();
    }
}

打印流

java.io.PrintStream打印流

PrintStream:為其他輸出流添加了功能燕酷,使它們能夠方便地打印各種數(shù)據(jù)值表示形式籍凝。

PrintStream特點(diǎn):

  1. 只負(fù)責(zé)數(shù)據(jù)的輸出,不負(fù)責(zé)數(shù)據(jù)的讀取

  2. 于其他輸出流不同苗缩,PrintStream 永遠(yuǎn)不會(huì)拋出 IOException

  3. 有特有的方法,print,println

    void print(任意類型的值)

    void println(任意類型的值并換行)

構(gòu)造方法:

  • PrintStream(File file) 輸出的目的地是一個(gè)文件
  • PrintStream(OutputStream out) 輸出的目的地是一個(gè)字節(jié)輸出流
  • PrintStream(String fileName) 輸出的目的地是一個(gè)文件路徑

PrintStream extends OutputStream 所以饵蒂,PrintStream繼承自父類的成員方法

注意:

  • 如果使用繼承自父類的write方法寫數(shù)據(jù),那么查看數(shù)據(jù)的時(shí)候會(huì)查詢編碼表 97->a
  • 如果使用自己特有的方法print/println方法寫數(shù)據(jù)酱讶,寫的數(shù)據(jù)原樣輸出 97->97
package com.jz.printStream;

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class PrintStreamDemo01 {
    public static void main(String[] args) throws FileNotFoundException {
        // 創(chuàng)建PrintStream對(duì)象退盯,構(gòu)造方法中綁定要輸出的目的地
        PrintStream ps = new PrintStream("D:\\CODE\\JAVA\\IDEA\\IO\\print.txt");
        // 如果使用繼承自父類的write方法寫數(shù)據(jù),那么查看數(shù)據(jù)的時(shí)候會(huì)查詢編碼表 97->a
        ps.write(97);
        // 如果使用自己特有的方法print/println方法寫數(shù)據(jù),寫的數(shù)據(jù)原樣輸出 97->97
        ps.println(97);

        // System.setOut方法改變輸出語句的目的地改為參數(shù)中傳遞的打印流的目的地
        System.setOut(ps);
        System.out.println("我在打印流的目的地輸出");
        ps.close();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末得问,一起剝皮案震驚了整個(gè)濱河市囤攀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宫纬,老刑警劉巖焚挠,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異漓骚,居然都是意外死亡蝌衔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝌蹂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來噩斟,“玉大人,你說我怎么就攤上這事孤个√暝剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵齐鲤,是天一觀的道長斥废。 經(jīng)常有香客問我,道長给郊,這世上最難降的妖魔是什么牡肉? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮淆九,結(jié)果婚禮上统锤,老公的妹妹穿的比我還像新娘。我一直安慰自己炭庙,他們只是感情好饲窿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著焕蹄,像睡著了一般逾雄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擦盾,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天嘲驾,我揣著相機(jī)與錄音,去河邊找鬼迹卢。 笑死辽故,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腐碱。 我是一名探鬼主播誊垢,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掉弛,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了喂走?” 一聲冷哼從身側(cè)響起殃饿,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芋肠,沒想到半個(gè)月后乎芳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帖池,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年奈惑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睡汹。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肴甸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出囚巴,到底是詐尸還是另有隱情原在,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布彤叉,位于F島的核電站庶柿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏姆坚。R本人自食惡果不足惜澳泵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一实愚、第九天 我趴在偏房一處隱蔽的房頂上張望兼呵。 院中可真熱鬧,春花似錦腊敲、人聲如沸击喂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懂昂。三九已至,卻和暖如春没宾,著一層夾襖步出監(jiān)牢的瞬間凌彬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工循衰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铲敛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓会钝,卻偏偏與公主長得像伐蒋,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容