Java进阶学习11:【缓冲流、编码表、转换流、序列化和反序列化、打印流】

  • A+
所属分类:Java Java进阶

01. 传统的字节流带来的效率问题

/*
    使用昨天的字节流复制文件, 并记录复制所占用的时间。
    10616ms
 */
public class Demo01CopyFile {
    public static void main(String[] args) throws IOException {
        //创建字节输入流,用来读取
        InputStream is = new FileInputStream("day11\\aa.jpg");
        //创建字节输出流,用来写
        OutputStream os = new FileOutputStream("day11\\bb.jpg");
        long start = System.currentTimeMillis();

        //开始读写,一次读写一个字节
        int i;
        while((i = is.read()) != -1) {
            os.write(i);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        //释放资源
        os.close();
        is.close();

    }
}

02. 缓冲流的使用以及使用缓冲流一次读写一个字节复制文件

/*
    缓冲流
        字节缓冲流
            BufferedOutputStream
            BufferedInputStream
        字符缓冲流:
            BufferedWriter
            BufferedReader

    缓冲流它的特点是可以提高读写的效率, 原因是因为内部有一个缓冲区, 这个缓冲区可以起到加速的作用。
    缓冲流其实本身并不具备读或者写的功能, 它的作用是给其他流提供加速。

    字节缓冲流的构造方法
        BufferedOutputStream(OutputStream out): 参数要传递一个字节输出流。
        BufferedInputStream(InputStream in): 参数要传递一个字节输入流。

    字节缓冲流用于读写的方法:
        字节缓冲流也属于字节流, 里面读写的方法和昨天学习的字节流的读写的方法一模一样

    字节缓冲流的使用步骤:
        1. 创建字节缓冲流。
        2. 读或者写
        3. 释放资源

    206ms
 */
public class Demo02BufferedStream {
    public static void main(String[] args) throws IOException {
        //创建字节输入缓冲流,用于读取
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day11\\aa.jpg"));
        //创建字节输出缓冲流,用来写入
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11\\bb.jpg"));
        long start = System.currentTimeMillis();
        //开始读写,一次读写一个字节。
        int i;
        while((i = bis.read()) != -1) {
            bos.write(i);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        //释放资源
        bos.close();
        bis.close();
    }
}

03. 缓冲流一次读写一个字节数组复制文件

/*
    使用字节缓冲流一次读写一个字节数组的方式复制文件
    7ms
 */
public class Demo03BufferedStream {
    public static void main(String[] args) throws IOException {
        //创建一个字节输入缓冲流,用来读取
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day11\\aa.jpg"));
        //创建一个字节输出缓冲流,用来写
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11\\bb.jpg"));

        long start = System.currentTimeMillis();

        //开始读写,一次读写一个字节数组
        byte[] bArr = new byte[1024 * 8];
        int len;
        while((len = bis.read(bArr)) != -1) {
            bos.write(bArr, 0, len);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        //释放资源
        bos.close();
        bis.close();

    }
}

04. 字符输出缓冲流写数据

/*
    BufferedWriter是字符输出缓冲流, 属于字符流, 使用方式和字符流是一样的。

    BufferedWriter构造方法:
        BufferedWriter(Writer out): 参数要传递给字符输出流。

    BufferedWriter写数据的方法:
        BufferedWriter中写数据的方法和之前学习的字符流写数据的方法一模一样

    使用步骤:
        1. 创建流
        2. 写数据。
        3. 刷新(字符输出流需要刷新)
        4. 释放资源
 */
public class Demo04BufferedWriter {
    public static void main(String[] args) throws IOException {
        //创建BufferedWriter对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\file01.txt"));
        //调用write方法,写数据
        bw.write("雷猴");
        //刷新
        bw.flush();
        //关流
        bw.close();
    }
}

05. 字符输入缓冲流读取数据

/*
    BufferedReader是字符输入缓冲流, 可以读取数据, 使用方式和之前的字符输入流一样。

    BufferedReader构造方法:
        BufferedReader(Reader in): 参数要传递一个字符输入流。

    BufferedReader读取的方法
        BufferedReader用于读取的方法和之前的字符输入流一模一样。

    使用步骤:
        1. 创建流
        2. 读取
        3. 关流
 */
public class Demo05BufferedReader {
    public static void main(String[] args) throws IOException {
        //创建字符输入缓冲流对象
        BufferedReader br = new BufferedReader(new FileReader("day11\\file01.txt"));
        //进行读取,一次读取一个字符数组
        char[] cArr = new char[1024];
        int len;
        while((len = br.read(cArr)) != -1) {
            System.out.print(new String(cArr, 0, len));
        }

        //进行读取, 一次读取一个字符的。
        /*
        int i;
        while((i = br.read()) != -1) {
            System.out.print((char)i);
        }
        */
        br.close();
    }
}

06. 字符缓冲流的特有的方法

/*
    字符缓冲流中的特有的功能:
        在BufferedWriter中有一个方法,可以实现一个跨平台的换行:
            void newLine(): 实现一个跨平台的换行

        在BufferedReader中有一个方法,可以读取一行数据。
            String readLine():读取一行数据并返回读取到的数据。 如果已经读取结束了, 返回null。
                               这个readLine不会读取换行符, 如果要进行换行操作,需要我们手动添加
 */
public class Demo06BufferedStream {
    public static void main(String[] args) throws IOException {
        method2();
    }

    /*
        String readLine():读取一行数据并返回读取到的数据。 如果已经读取结束了, 返回null。
     */
    public static void method2() throws IOException {
        //创建BufferedReader对象,用来读取
        BufferedReader br = new BufferedReader(new FileReader("day11\\file01.txt"));
        //使用循环去读取
        //定义变量,保存每次读取到的一行数据
        String line;
        //开始循环
        /*
            条件位置做了哪些事情:
                1. 通过输入流调用readLine方法读取一行数据。
                2. 将读取到的这行数据赋值给变量line。
                3. 判断line是否不等于null,如果line不是null表示读取到了数据,那么就可以进行处理
         */
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }

        /*
        //调用readLine方法,读取一行数据
        String line = br.readLine();
        System.out.println(line);//床前明月光

        line = br.readLine();
        System.out.println(line);//疑是地上霜

        line = br.readLine();
        System.out.println(line);//null
        */
        br.close();
    }

    /*
        void newLine(): 实现一个跨平台的换行
     */
    public static void method() throws IOException {
        //创建一个字符输出缓冲流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\file01.txt"));
        //向文件写两句诗
        bw.write("床前明月光");
        //bw.write("\r\n");
        //void newLine(): 实现一个跨平台的换行
        bw.newLine();
        bw.write("疑是地上霜");
        bw.close();
    }
}

07. 缓冲流恢复顺序的练习

/*
    将出师表.txt中的文本恢复顺序,并写入到一个新的文件中。

    文件特点:
        1. 每行数据都是采用 序号.课文内容 这样的格式
        2. 里面的序号都是唯一的, 都不重复。

    思路:
        1. 定义一个Map集合, 保存序号以及课文内容的对应关系。
        2. 创建BufferedReader,用来读取数据。
        3. 开始读取,一次读取一行数据。
        4. 根据.切割读取到的这行数据, 得到序号以及课文内容。
        5. 将序号以及课文内容添加到Map集合。
        6. 关闭输入流。
        7. 创建BufferedWriter,用来写。
        8. 使用循环手动拿到1-9之间的每一个数字(序号)
        9. 通过Map集合,拿到这个序号所对应的课文内容。
        10. 将序号以及课文内容写到新的文件。
        11. 换行
        12. 刷新
        13. 释放资源。
 */
public class Demo07Test {
    public static void main(String[] args) throws IOException {
        //定义一个Map集合, 保存序号以及课文内容的对应关系。
        Map<Integer, String> map = new HashMap<>();
        //创建BufferedReader,用来读取数据。
        BufferedReader br = new BufferedReader(new FileReader("day11\\出师表.txt"));
        //开始读取,一次读取一行数据。
        String line;
        while((line = br.readLine()) != null) {
            //line中保存的就是读取到的这一行
            //根据.切割读取到的这行数据, 得到序号以及课文内容。
            //strArr[0] 表示序号。 strArr[1]表示课文内容
            String[] strArr = line.split("\\."); //根据.切割,要写\\.
            //将序号转成Integer类型
            Integer id = Integer.parseInt(strArr[0]);
            //将序号以及课文内容添加到Map集合。
            map.put(id, strArr[1]);
        }
        //关闭输入流。
        br.close();
        //创建BufferedWriter,用来写。
        BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\outTeacherTable.txt"));
        //使用循环手动拿到1-9之间的每一个数字(序号)
        for(int i = 1; i <= 9; i++) {
            //i是1-9之间的每一个数字,同时也表示序号。
            //通过Map集合,拿到这个序号所对应的课文内容。
            String value = map.get(i);
            //将序号以及课文内容写到新的文件。
            bw.write(i + "." + value);
            //换行
            bw.newLine();
            //刷新
            bw.flush();
        }
        //释放资源
        bw.close();
    }
}

08. 编码表

计算机中保存的数据都是字节
我们在计算机中看到的是字符(汉字,英文)

字符 -> 字节: 编码
字节 -> 字符: 解码

编码表(字符集): 是字节和字符的对应关系表。

常见的编码表:
ASCII:  1字节     一共有128个字符(常见的英文字母标点符号等)
IOS8859-1(Latin):  1字节  一共有256个字符。 除了支持常见的英文字母以及符号外,还支持拉丁文。
GB2312:  1/2字节          一共有六千多个汉字以及其他符号 
BIG5:  1/2字节。           支持繁体字。
GBK:   1/2字节。           支持两万多个汉字。

Unicode:国际标准码表。 可以表示所有国家的所有的语言。 Unicode8.0甚至支持emoji。  在Unicode中任何东西都是占2个字节。

基于Unicode,出现了UTF-8
UTF-32: 每个字符占4个字节。
UTF-16: 每个字符占2/3/4个字节。
UTF-8: 每个字符占1/2/3/4个字节。

只需要记住GBK和UTF-8。
windows操作系统默认的编码是GBK。
IDEA默认的编码是UTF-8

在GBK中,一个中文占两个字节。
在UTF-8中, 一个中文占三个字节。

09. 字符流引发的乱码问题

/*
    使用FileReader读取文件:

    FileReader会采用开发环境的编码去读取,现在idea采用的是默认编码utf-8, 所以FileReader会采用UTF-8读
    在windows中,采用的默认编码是GBK,我们在操作系统中新建的文件aa.txt默认是GBK编码,两种编码不一致,于是就引发的乱码问题
 */
public class Demo01FileReader {
    public static void main(String[] args) throws IOException {
        //创建FileReader对象
        Reader r = new FileReader("d:\\aa.txt");
        //读取数据,一次读取一个字符
        int i;
        while ((i = r.read()) != -1) {
            System.out.print((char)i);
        }
        //释放资源
        r.close();
    }
}

10. 转换流指定编码读取数据

/*
    InputStreamReader是转换流, 可以指定编码进行读取。
    InputStreamReader是字符流, 会以字符为单位进行读取, 这个流的使用方式和之前的字符输入流一致。

    InputStreamReader构造方法:
        InputStreamReader(InputStream in):参数要传递一个字节输入流。  使用这个构造方法创建的转换流对象会采用开发环境的编码去读取数据。
        InputStreamReader(InputStream in, String charsetName):第一个参数是一个输入流, 第二个参数是编码的名字,会采用指定的编码进行读取。

    InputStreamReader读取数据的方法:
        InputStreamReader里面的读取数据的方法和之前字符流读取数据的方法一模一样。

    使用步骤:
        1. 创建一个InputStreamReader用来指定编码进行读取。
        2. 调用read方法进行读取。
        3. 释放资源

    使用转换流创建对象的时候指定的编码必须存在, 否则会报错。

    小结:
        文件采用的是什么编码, 那么转换流就要指定什么编码去读取。
 */
public class Demo02InputStreamReader {
    public static void main(String[] args) throws IOException {
        readUTF8();
    }
    //读取UTF-8的文件
    public static void readUTF8() throws IOException {
        //创建一个InputStreamReader,指定以UTF-8的方式读取文件
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\aa.txt"), "UTF-8");
        InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\bb.txt"), "UTF-8");
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\bb.txt"));//如果不指定编码,那么就会以UTF-8的方式读取
        //开始读取
        //开始读取,一次读取一个字符。
        int i;
        while((i = isr.read()) != -1) {
            System.out.print((char) i);
        }
        //释放资源
        isr.close();
    }

    //读取GBK文件。
    public static void readGBK() throws IOException {
        //创建一个InputStreamReader用来指定编码进行读取。
        InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\aa.txt"), "GBK");
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\bb.txt"), "GBK");
        //开始读取,一次读取一个字符。
        int i;
        while((i = isr.read()) != -1) {
            System.out.print((char) i);
        }
        //释放资源
        isr.close();
    }
}

11. 转换流指定编码写数据

/*
    OutputStreamWriter也是转换流, 用来写, 可以指定编码写数据。

    OutputStreamWriter构造方法:
        OutputStreamWriter(OutputStream out): 参数要传递一个字节输出流, 使用这个构造方法创建的转换流对象会采用开发环境的编码写数据。
        OutputStreamWriter(OutputStream out, String charsetName): 第一个参数是字节输出流, 第二个参数为指定的编码方式,会以指定的编码去写数据。

    OutputStreamWriter里面写数据的方法和字符流写数据的方法一模一样, 以为OutputStreamWriter是字符流的一种。

    使用步骤:
        1. 创建流
        2. 写数据。
        3. 刷新。
        4. 释放资源
 */
public class Demo03OutputStreamWriter {
    public static void main(String[] args) throws IOException {
        //writeGBK();
        writeUTF8();
    }

    /*
        定义方法,向文件中写UTF-8编码的数据
     */
    public static void writeUTF8() throws IOException {
        //创建转换流
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\file02-utf8.txt"), "utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\file02-utf8.txt"));
        //调用write方法,写数据
        osw.write("你好");
        //刷新
        osw.flush();
        //释放资源
        osw.close();
    }

    /*
        定义方法, 用来向文件中写GBK编码的数据
     */
    public static void writeGBK() throws IOException {
        //创建OutputStreamWriter对象, 指定GBK进行写
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\file01-gbk.txt"), "GBK");
        //调用write方法,写数据
        osw.write("你好");
        //刷新
        osw.flush();
        //关流
        osw.close();
    }
}

12. 缓冲流的流向图解

参考 Java基础学习19:【缓冲流、转换流、序列化流】中的图

13. 转换流的练习

/*
    将GBK编码的文本文件,转换为UTF-8编码的文本文件。

    在读取的时候指定以GBK的方式读取文件, 在写的时候指定以UTF-8的方法写即可。

    步骤:
        1. 创建InputStreamReader,指定以GBK的方式进行读取。
        2. 创建OutputStreamWriter, 指定以UTF-8的方式进行写。
        3. 一边读,一边写, 每读取到数据就写到目的地文件中。
        4. 刷新
        5. 释放资源。
 */
public class Demo04Test {
    public static void main(String[] args) throws IOException {
        //创建InputStreamReader,指定以GBK的方式进行读取。
        InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\file03-gbk.txt"), "GBK");
        //创建OutputStreamWriter, 指定以UTF-8的方式进行写。
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\file04-utf8.txt"), "UTF-8");
        //一边读,一边写, 每读取到数据就写到目的地文件中。
        int i;
        while((i = isr.read()) != -1) {
            //将读取出来的数据写到新的文件中
            osw.write(i);
            //刷新
            osw.flush();
        }
        //释放资源
        osw.close();
        isr.close();
    }
}

14. 序列化和反序列化图解

参考 Java基础学习19:【缓冲流、转换流、序列化流】中的图

15. 使用序列化流写对象

/*
    ObjectOutputStream叫做序列化流, 可以将Java程序中的对象写到文件中。

    ObjectOutputStream构造方法:
        ObjectOutputStream(OutputStream out): 参数要传递一个字节输出流对象。

    ObjectOutputStream写对象方法:
        void writeObject(Object obj): 向文件中写一个对象

    序列化流的使用步骤:
        1. 创建ObjectOutputStream序列化流
        2. 调用writeObject,写对象
        3. 释放资源

    要使用序列化流写入的对象, 一定要实现Serializable接口。
 */
public class Demo01ObjectOutputStream {
    //向文件写Person对象。
    public static void main(String[] args) throws IOException {
        //创建ObjectOutputStream序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\file02-obj.txt"));
        //调用writeObject,写对象
        Person p = new Person("刘备", 12);
        oos.writeObject(p);

        //释放资源
        oos.close();
    }
}

/*
    Serializable里面没有任何的方法, 这个接口仅仅会起到一个标记的作用。
    只有实现这个接口之后, 这个类的对象才可以写到文件中。
 */
public class Person implements Serializable {
    private String name;
    private /* static */ /*transient*/ int age;

    //serialVersionUID表示固定了该类的版本号是1, 无论怎么修改这个类,这个类的版本号都是1.
    private static final long serialVersionUID = 1L;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + 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;
    }
}

16. 使用反序列化流读取对象

/*
    ObjectInputStream是反序列化流, 可以将文件中的对象读取到Java程序中。

    ObjectInputStream构造方法:
        ObjectInputStream(InputStream in): 参数要传递一个字节输入流。

    ObjectInputStream读取对象的方法:
        Object readObject(): 从文件中读取对象, 并将读取到的对象返回。

    反序列化的步骤:
        1. 创建一个反序列化流对象,用来读取
        2. 调用readObject方法进行读取操作。
        3. 调用close方法释放资源。

    如果进行读取的时候, 文件中保存的对象所属的类已经不存在了,那么就会报错。
 */
public class Demo02ObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建一个反序列化流对象,用来读取
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\file02-obj.txt"));
        //调用readObject方法进行读取操作。
        Object obj = ois.readObject();
        System.out.println(obj);

        //Person p = (Person) obj;
        //System.out.println(p.getName() + "-" + p.getAge());

        //释放资源
        ois.close();
    }
}

17. 序列化中的transient关键字

/*
    注意:
        1. 如果一个成员使用了静态修饰,那么该成员无法被序列化。 因为静态修饰的成员是属于类的,不属于对象,
           而此时序列化流写的是对象。

        2. 如果不希望某个成员变量被写入到文件,同时又不希望使用static关键字, 那么可以使用transient关键字。
           transient关键字表示瞬态,被这个关键字修饰的成员变量不能被序列化。
 */
public class Demo03StaticAndTransient {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //writeObject();
        readObject();
    }

    /*
        定义方法,从文件中读取一个Person对象
     */
    public static void readObject() throws IOException, ClassNotFoundException {
        //创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\file03-obj.txt"));
        //调用readObject方法,读取对象
        Object obj = ois.readObject();
        System.out.println(obj);

        //释放资源
        ois.close();
    }

    /*
        定义方法,向文件中写入一个Person对象
     */
    public static void writeObject() throws IOException {
        //创建一个序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\file03-obj.txt"));
        //调用writeObject方法写对象
        oos.writeObject(new Person("张三丰", 120));
        //释放资源
        oos.close();
    }
}

18. 序列化中的版本号问题

public class Demo04SerialVersionUID {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //writeObject();
        readObject();
    }

    /*
        定义方法,从文件中读取一个Person对象
     */
    public static void readObject() throws IOException, ClassNotFoundException {
        //创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\file03-obj.txt"));
        //调用readObject方法,读取对象
        Object obj = ois.readObject();
        System.out.println(obj);

        //释放资源
        ois.close();
    }

    /*
        定义方法,向文件中写入一个Person对象
     */
    public static void writeObject() throws IOException {
        //创建一个序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\file03-obj.txt"));
        //调用writeObject方法写对象
        oos.writeObject(new Person("张三丰", 120));
        //释放资源
        oos.close();
    }
}

/*
    如果要解决版本号不一致的问题,可以给类固定一个版本号,无论类怎么修改,版本号都不变。
    如何给类分配一个固定的版本号, 只需要在这个类中提供一个成员变量,叫做serialVersionUID
    serialVersionUID固定使用 private static final long 修饰
 */
public class Person implements Serializable {
    private String name;
    private /* static */ /*transient*/ int age;

    //serialVersionUID表示固定了该类的版本号是1, 无论怎么修改这个类,这个类的版本号都是1.
    private static final long serialVersionUID = 1L;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + 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;
    }
}

19. 序列化的练习

/*
    1. 将存有多个自定义对象的集合序列化操作,保存到list.txt 文件中。
    2. 反序列化list.txt ,并遍历集合,打印对象信息。

    创建多个Student对象添加到集合, 并将集合写到文件中, 然后再读取文件中的集合, 再遍历集合。
 */
public class Demo05Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //定义集合,用来保存Student对象
        ArrayList<Student> list = new ArrayList<>();
        //添加Student对象
        list.add(new Student("爱因斯坦", 20));
        list.add(new Student("爱迪生", 30));
        list.add(new Student("达芬奇", 40));

        //将保存学生对象的集合写到文件中
        //创建序列化流对象,用来写
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\list.txt"));
        //调用writeObject方法,写对象
        oos.writeObject(list);
        //释放资源
        oos.close();

        //将文件中的集合进行读取, 并遍历集合,打印集合中的每一个对象
        //创建反序列化流对象,用来读取
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\list.txt"));
        //调用反序列化流的readObject读取对象
        ArrayList<Student> list2 = (ArrayList<Student>)ois.readObject();
        //遍历打印读取到的集合
        for (Student s : list2) {
            System.out.println(s);
        }
        //释放资源
        ois.close();
    }
}
public class Student implements Serializable{
    private String name;
    private int age;

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

    public Student() {
    }

    public Student(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;
    }
}

20. 打印流的使用

/*
    PrintStream是打印流, 打印流是输出流的一种, 打印流有下面特点:
        1. 打印流只有输出,没有输入。
        2. 输出数据十分方便。

    PrintStream的构造方法:
        PrintStream(String fileName): 参数要传递一个字符串类型的文件路径。
        PrintStream(File file): 参数要传递一个File类型的文件。
        PrintStream(OutputStream out): 传递要传递一个字节输出流。

    PrintStream写数据的方法(特有的方法):
        void print(任意类型): 输出数据,但是不会换行。
        void println(任意类型): 输出数据,但是会换行。

    使用步骤:
        1. 创建打印流
        2. 写数据。
        3. 关流。
 */
public class Demo01PrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        //创建打印流
        PrintStream ps = new PrintStream("day11\\file04-obj.txt");
        //写数据
        //ps.print("你好");
        //ps.print("我好");

        ps.println("你好");
        ps.println("我好");

        //释放资源
        ps.close();

    }
}

/*
    我们之前使用的System.out.println中的System.out其实就是打印流。
    这个System.out打印流的目的地默认是控制台。

    在System中有一个方法,可以改变System.out的目的地
        static void setOut(PrintStream out):参数要传递一个PrintStream打印流, 传递的打印流目的地是什么,将来使用System.out.println就向哪里输出数据。

 */
public class Demo02PrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        //创建打印流
        PrintStream ps = new PrintStream("day11\\file05.txt");
        //调用System.setOut改变目的地
        System.setOut(ps);
        System.out.println("你好");
    }
}
  • 资源分享QQ群
  • weinxin
  • 官方微信公众号
  • weinxin
沙海
Linux服务器网站环境安装
动力节点最牛Java自学基础教程
网站https安全证书安装,伪静态配置
一个Java基础入门的教程视频

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: