【Java基础复习】IO流(三)

zbhgis 浩瀚地学5153 分钟
创建于 更新于

个人主页:https://github.com/zbhgis

前言

1.之前学过,因此本文是个人复习笔记,为视频的总结以及个人思考,可能不是很详细。

2.教程是b站黑马程序员的JAVASE基础课程,笔记中的大部分图片来自于视频中的PPT截图。

3.Java环境为Java SE 17.0.3.1,IntelliJ IDEA版本为2025.2

https://www.bilibili.com/video/BV1Cv411372m

内容概览

1.本文内容主要包括字符流,缓冲流,以及缓冲流的性能分析

2.笔记对应视频161-163节

更新记录

创建时间:2025.10 完成初步撰写

更新1:2026.03 补充目录,并添加个人github主页链接

字符流

FileReader(文件字符输入流)

作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。

img

Io11.java

Java
package com.zbhgis.io;

import java.io.*;

public class Io11 {
    public static void main(String[] args) {
        try (
                Reader fr = new FileReader("E:/AAAfile/gee_bakup/aaa/bb.txt");
                Reader fr2 = new FileReader("E:/AAAfile/gee_bakup/aaa/bb.txt");
        ) {
            int c;
            while ((c = fr.read()) != -1) {
                System.out.print((char) c);
            }
            System.out.println("\r\n");


            char[] buffer = new char[3];
            int len;
            while ((len = fr2.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

打印结果

Plain
asdfghjkl;'\
学java
不想学
Python和Java都学

asdfghjkl;'\
学java
不想学
Python和Java都学

FileWriter(文件字符输出流)

作用:以内存为基准,可以把文件中的数据以字符的形式写出到文件中。

字符输出流写出数据后,必须刷新流,或者关闭流,写出的数据才会生效。

img

Io12.java

Java
package com.zbhgis.io;

import java.io.FileWriter;
import java.io.Writer;

public class Io12 {
    public static void main(String[] args) throws Exception {
        Writer fw = new FileWriter("E:/AAAfile/gee_bakup/aaa/ff.txt");

        fw.write('a');
        fw.write("bcd");
        fw.write("\r\n");
        fw.write("中国");

        fw.flush(); // 刷新流,刷新之后还能使用流
        fw.write("第一");
        fw.close(); // 关闭流之后就不能再使用了
    }
}

ff.txt

Plain
abcd
中国第一

缓冲流

img

BufferedInputStream(字节缓冲流)

提供字节流读写数据的性能,原理在于其自带了8KB缓冲池

img

Io13.java

Java
package com.zbhgis.io;

import java.io.*;

public class Io13 {
    public static void main(String[] args) {
        try (
                InputStream is = new FileInputStream("E:/AAAfile/gee_bakup/aaa/bb.txt");
                InputStream bis = new BufferedInputStream(is, 8192 * 2);

                OutputStream os = new FileOutputStream("E:/AAAfile/gee_bakup/aaa/gg.txt");
                OutputStream bos = new BufferedOutputStream(os, 8192 * 2);
        ) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            System.out.println("复制完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedReader(字符缓冲输入流)

自带了8k的字符缓冲池,可以提高字符输入流读取字符数据的性能。

img img

Io14.java

Java
package com.zbhgis.io;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;

public class Io14 {
    public static void main(String[] args) throws Exception {
        try (
                Reader fr = new FileReader("E:/AAAfile/gee_bakup/aaa/bb.txt");
                BufferedReader br = new BufferedReader(fr);
                Reader fr2 = new FileReader("E:/AAAfile/gee_bakup/aaa/bb.txt");
                BufferedReader br2 = new BufferedReader(fr2);
        ) {
            char[] buffer = new char[3];
            int len;
            while ((len = br.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
            System.out.println("\r\n");

            String line;
            while ((line = br2.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印结果

Plain
asdfghjkl;'\
学java
不想学
Python和Java都学

asdfghjkl;'\
学java
不想学
Python和Java都学

BufferedWriter(字符缓冲输出流)

自带了8k的字符缓冲池,可以提高字符输出流写字符数据的性能。

img img

Io15.java

Java
package com.zbhgis.io;

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

public class Io15 {
    public static void main(String[] args) throws Exception {
        try (
                Writer fw = new FileWriter("E:/AAAfile/gee_bakup/aaa/hh.txt");
                BufferedWriter bw = new BufferedWriter(fw);
        ) {
            fw.write('a');
            fw.write("bcd");
            fw.write("\r\n");
            fw.write("中国");

            fw.flush(); // 刷新流,刷新之后还能使用流
            fw.write("第一");
            fw.close(); // 关闭流之后就不能再使用了
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

性能分析

使用低级字节流或者缓冲流用字节数组进行复制的效果最好,给的缓冲块大小越大越好,但大到一定程度就不起作用了。

Io16.java

Java
package com.zbhgis.io;

import java.io.*;

public class Io16 {
    private static final String SRC_FILE = "E:/AAAtest/test.jp2";
    private static final String DEST_FILE = "E:/AAAtest/";

    public static void main(String[] args) {
        // copy01();  // 方法一耗时太长
        copy02(); // 139ms
        copy03(); // 1572ms
        copy04(); // 131ms
    }

    private static void copy01() {
        long start = System.currentTimeMillis();
        try (
                InputStream is = new FileInputStream(SRC_FILE);
                OutputStream os = new FileOutputStream(DEST_FILE + "1.jp2");
        ) {
            int b;
            while ((b = is.read()) != -1) {
                os.write(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("低级字节流一个个字节复制:" + (end - start) + "ms");
    }

    private static void copy02() {
        long start = System.currentTimeMillis();
        try (
                InputStream is = new FileInputStream(SRC_FILE);
                OutputStream os = new FileOutputStream(DEST_FILE + "2.jp2");
        ) {
            byte[] buffer = new byte[1024 * 8];
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("低级字节流用字节数组复制:" + (end - start) + "ms");
    }

    private static void copy03() {
        long start = System.currentTimeMillis();
        try (
                InputStream is = new FileInputStream(SRC_FILE);
                BufferedInputStream bis = new BufferedInputStream(is);
                OutputStream os = new FileOutputStream(DEST_FILE + "3.jp2");
                BufferedOutputStream bos = new BufferedOutputStream(os);
        ) {
            int b;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("缓冲流一个个字节复制:" + (end - start) + "ms");
    }

    private static void copy04() {
        long start = System.currentTimeMillis();
        try (
                InputStream is = new FileInputStream(SRC_FILE);
                BufferedInputStream bis = new BufferedInputStream(is);
                OutputStream os = new FileOutputStream(DEST_FILE + "4.jp2");
                BufferedOutputStream bos = new BufferedOutputStream(os);
        ) {
            byte[] buffer = new byte[1024 * 8];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("缓冲流用字节数组复制:" + (end - start) + "ms");
    }
}

打印结果

Plain
低级字节流用字节数组复制:140ms
缓冲流一个个字节复制:2381ms
缓冲流用字节数组复制:135ms

总结

1.字符流读取中文字符更友好

2.缓冲流有内置默认8KB的缓冲池,其读写效率更高

3.低级字节流或缓冲流使用字节数组复制效率更高