---
title: "【Java基础复习】IO流（三）"
source: https://www.zbhgis.com/note/note-20250921-1
author: zbhgis 浩瀚地学
created: 2025-09-21
tags: [Java基础复习, Java]
---

> 本文来自浩瀚地学，规范页面（含代码高亮与图片灯箱）：https://www.zbhgis.com/note/note-20250921-1
# 【Java基础复习】IO流（三）

个人主页：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](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072242780.png)

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](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072242108.png)

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](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072242919.png)

## BufferedInputStream（字节缓冲流）

提供字节流读写数据的性能，原理在于其自带了8KB缓冲池

![img](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072241382.png)

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](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072241493.png)

![img](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072242303.png)

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](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072242037.png)

![img](https://cdn.jsdelivr.net/gh/zbhgis/BlogImg@main/blog/202607072241046.png)

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.低级字节流或缓冲流使用字节数组复制效率更高
