javaIO的BIO

一、BIO 整体认知

BIO:同步阻塞 IO

  1. 线程发起读写请求后,会一直阻塞等待,直到读写完成
  2. 流是单向:输入只能读、输出只能写
  3. 两大顶层抽象父类(固定记)
  • 字节流(一切文件通用):InputStream / OutputStream
  • 字符流(仅文本):Reader / Writer

一、字节流(万能流)

1. 基础文件字节流

核心类

  • FileInputStream:文件(字节输入)
  • FileOutputStream:文件(字节输出)

核心特点

  1. 字节读写,所有文件:图片、视频、压缩包、文本全能操作
  2. 不会处理编码,纯原始字节
  3. 单字节读写效率极低,只适合入门理解

示例:单字节读取 & 写入

1
2
3
4
5
6
7
8
9
10
// 读取
try (FileInputStream fis = new FileInputStream("test.txt")) {
int b;
// 返回字节码,读到末尾返回 -1
while ((b = fis.read()) != -1) {
System.out.print((char) b);
}
} catch (IOException e) {
e.printStackTrace();
}
1
2
3
4
5
6
// 覆盖写入|追加写入 new FileWriter(path,true)
try (FileOutputStream fos = new FileOutputStream("out.txt")) {
fos.write("hello io".getBytes());
} catch (IOException e) {
e.printStackTrace();
}

2. 缓冲字节流(开发常用)

核心类

BufferedInputStream / BufferedOutputStream

底层原理

内部自带缓冲区数组,默认 8192 字节

减少频繁磁盘 IO 交互,大幅提升大文件读写性能

高效文件复制(工作常用模板)

1
2
3
4
5
6
7
8
9
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg"))) {

byte[] buf = new byte[1024];
int len;
while ((len = bis.read(buf)) != -1) {
bos.write(buf,0,len);
}
}

二、字符流(只用于纯文本)

1. 基础文件字符流

核心类

FileReader / FileWriter

特点

  1. 字符读取,自动适配本地默认编码
  2. 专门处理文本,天然降低中文乱码概率
  3. 不能操作图片、视频等二进制文件

2. 缓冲字符流(文本开发必用)

核心类

BufferedReader / BufferedWriter

核心优势

  • readLine()按行读取,处理日志、配置文件超级方便
  • 自带字符缓冲,效率高
1
2
3
4
5
6
7
// 按行读取文本
try (BufferedReader br = new BufferedReader(new FileReader("doc.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}

关键区别总结

字节流:一切文件、无编码、适合二进制

字符流:仅文本、带编码、适合中文、按行处理


三、转换流(解决乱码核心)

痛点

FileReader/FileWriter 强制使用系统默认编码,跨平台必然乱码。

核心作用

实现字节流 ↔ 字符流转换,手动指定编码

两个核心类

  1. InputStreamReader:字节输入 → 字符输入(读,指定编码)
  2. OutputStreamWriter:字节输出 → 字符输出(写,指定编码)

标准指定编码读写(企业规范写法)

1
2
3
4
5
6
7
8
// 以UTF-8读取
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("text.txt"),"UTF-8"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}

开发规范:文本 IO 一律手动指定 UTF-8,杜绝乱码


四、打印流(简化输出)

核心类

PrintStream(字节)、PrintWriter(字符,更常用)

特点

  1. 提供大量重载方法:print/println/printf
  2. 自动刷新、无需手动刷缓冲区
  3. 不会抛出编译期异常
  4. 日常:System.out 本质就是 PrintStream
1
2
3
4
try (PrintWriter pw = new PrintWriter("log.txt")) {
pw.println("日志信息1");
pw.println("日志信息2");
}

五、对象流|序列化

作用

内存中的对象转为字节数据,实现持久化 / 网络传输

核心类

  • ObjectOutputStream:序列化(对象 → 字节)
  • ObjectInputStream:反序列化(字节 → 对象)

强制约束

实体类必须实现:Serializable 标记接口(无方法,仅做标记)

关键关键字

  • transient:被修饰的成员变量不会被序列化,临时数据、敏感字段常用

极简示例

1
2
3
4
5
6
7
8
9
10
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.obj"))) {
User user = new User("张三",20);
oos.writeObject(user);
}

// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.obj"))) {
User user = (User) ois.readObject();
}

六、BIO 资源关闭|try-with-resources

旧写法(淘汰)

finally 手动 close,代码冗余、容易漏关、引发文件句柄泄漏

JDK7+ 标准写法(必掌握)

实现 AutoCloseable 接口的流,都可以放在 try()

代码执行完毕,自动关闭流,无需手动 close

1
2
3
4
5
6
// 格式固定:try(定义流对象) { 业务 }
try (FileInputStream fis = new FileInputStream("a.txt")){
// 读写逻辑
} catch (IOException e){
e.printStackTrace();
}

底层原理

编译期自动生成 finally 代码块调用 close 方法,优雅关闭资源。


javaIO的BIO
http://hanqichuan.com/2026/04/20/java的IO/javaIO的BIO/
作者
韩启川
发布于
2026年4月20日
许可协议