IO 流是 Java 实现文件读写、数据传输的核心体系,分为字节流与字符流两大分支。本文围绕 IO 基础概念、四大文件基础流、Properties 配置集合、Hutool 简化工具库完整讲解,配套构造方法表格、读写代码、文件拷贝实战、异常标准处理,适合零基础自学、期末复习、面试查漏补缺。
一、IO 介绍和分类
1.1 IO 基础概念
I = Input 输入(读取外部数据到程序)O = Output 输出(程序写出数据到外部文件)IO 流就是程序和文件之间的数据传输管道。常见使用场景:读写日志 / 配置文件、文件上传下载、网络数据交互。
1.2 IO 流整体体系划分
IO 流分为字节流、字符流两套抽象体系:
- 字节流(万能流,所有文件均可读写,图片 / 视频 / 压缩包等二进制文件必用)
- 顶层抽象父类:
InputStream(字节输入)、OutputStream(字节输出) - 文件实现类:
FileInputStream、FileOutputStream
- 字符流(仅适用于纯文本文件,解决中文乱码)
- 顶层抽象父类:
Reader(字符输入)、Writer(字符输出) - 文件实现类:
FileReader、FileWriter
1.3 小结
字节流适配所有类型文件;字符流只操作 txt 等纯文本;所有流使用完毕必须关闭释放资源。
二、FileOutputStream 字节输出流
2.1 概述
字节输出流,负责把程序数据写入磁盘文件,以字节为单位传输。
2.2 构造方法
| 构造方法 | 说明 |
|---|---|
| FileOutputStream(String name) | 传入文件路径字符串创建输出流 |
| FileOutputStream(File file) | 传入 File 文件对象创建输出流 |
| FileOutputStream(String name, boolean append) | append=true 开启追加写入,false 覆盖原文件 |
| FileOutputStream(File file, boolean append) | File 对象形式的追加构造 |
关键注意
- 文件不存在:自动创建空文件;
- 文件存在、无追加参数:打开流时直接清空原有全部内容。
2.3 核心写入方法
| 方法 | 说明 |
|---|---|
| void write(int b) | 写出单个字节 |
| void write(byte[] b) | 一次性写出整个字节数组 |
| void write(byte[] b, int off, int len) | 写出数组中从 off 开始,长度为 len 的部分字节 |
2.4 关流与标准异常处理
流会占用操作系统资源,使用完必须调用close()关闭。JDK7 新增try-with-resources语法,自动实现关闭,无需手动 close,要求流类实现AutoCloseable接口。标准语法模板:
try (FileOutputStream fos = new FileOutputStream("D:/a.txt",true)){
// 读写业务代码
}catch (IOException e){
e.printStackTrace();
}
2.5 完整示例代码
import java.io.FileOutputStream;
import java.io.IOException;
public class FosDemo {
public static void main(String[] args) throws IOException {
// 追加写入模式
try (FileOutputStream fos = new FileOutputStream("D:/a.txt",true)){
byte[] arr = {97,98,99};
fos.write(arr);
fos.write("\r\n".getBytes()); // 换行
}
}
}
2.6 小结
FileOutputStream 负责字节写出;追加参数控制是否覆盖;优先使用 try-with-resources 自动释放资源。
三、FileInputStream 字节输入流
3.1 概述
字节输入流,从磁盘文件读取字节数据到程序,二进制文件读写必备。
3.2 构造方法
| 构造方法 | 说明 |
|---|---|
| FileInputStream(String name) | 字符串路径绑定文件 |
| FileInputStream(File file) | File 对象绑定文件 |
关键注意
文件不存在 / 传入文件夹路径,直接抛出FileNotFoundException文件不存在异常。
3.3 读取核心方法
| 方法 | 说明 |
|---|---|
| int read() | 读取单个字节,读到文件末尾返回 - 1 |
| int read(byte[] b) | 批量读取字节存入数组,返回本次读到的有效字节数;末尾返回 - 1 |
3.4 批量读取原理
定义固定长度字节数组作为缓冲区,循环读取,每次返回有效长度,根据长度截取有效内容,避免数组残留旧数据。
import java.io.FileInputStream;
import java.util.Arrays;
public class FisDemo {
public static void main(String[] args) throws Exception {
try (FileInputStream fis = new FileInputStream("D:/a.txt")){
byte[] buf = new byte[2];
int len;
while((len = fis.read(buf)) != -1){
System.out.println(Arrays.toString(buf)+" 读取长度:"+len);
}
}
}
}
3.5 实战案例:字节流文件拷贝
需求:将 D 盘图片复制到 E 盘,字节流支持所有格式文件。实现思路:输入流读源文件 + 输出流写目标文件,循环缓冲读写。
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyDemo {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("D:/嘿嘿.jpg");
FileOutputStream fos = new FileOutputStream("E:/嘿嘿.jpg")){
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) != -1){
fos.write(buf,0,len);
}
System.out.println("拷贝完成");
}catch (Exception e){
e.printStackTrace();
}
}
}
3.6 小结
FileInputStream 按字节读取;read 返回 - 1 代表文件读完;字节流可实现任意类型文件拷贝。
四、FileReader 字符输入流
4.1 概述
字符输入流,专门读取纯文本文件,自动处理中文编码,不会出现字节乱码。
4.2 构造方法
| 构造方法 | 说明 |
|---|---|
| FileReader(String fileName) | 字符串路径绑定文本文件 |
| FileReader(File file) | File 对象绑定文本文件 |
4.3 读取方法
| 方法 | 说明 |
|---|---|
| int read() | 读取单个字符,末尾返回 - 1 |
| int read(char[] cbuf) | 批量读取字符到字符数组,返回有效字符数量 |
4.4 小结
仅用于 txt、md 等纯文本;处理中文比字节流更友好,图片视频不可使用。
五、FileWriter 字符输出流
5.1 概述
字符输出流,向纯文本文件写入字符、字符串。
5.2 构造方法
| 构造方法 | 说明 |
|---|---|
| FileWriter(String fileName) | 普通覆盖写入 |
| FileWriter(String fileName, boolean append) | append=true 开启追加 |
| FileWriter(File file) | File 对象覆盖写入 |
| FileWriter(File file, boolean append) | File 对象追加写入 |
5.3 写入重载方法
| 方法 | 说明 |
|---|---|
| void write(int c) | 写入单个字符 |
| void write(char[] cbuf) | 写入整个字符数组 |
| void write(char[] cbuf, int off, int len) | 写入数组部分字符 |
| void write(String str) | 直接写入完整字符串 |
| void write(String str, int off, int len) | 写入字符串截取片段 |
5.4 关键特性:缓冲区刷新
字符流存在内存缓冲区,数据不会立刻写入磁盘:
flush():刷新缓冲区,数据写入文件,流可继续使用;close():先自动刷新缓冲区,再关闭流,关闭后无法读写。
5.5 小结
字符输出流必须刷新或关闭才会落盘;仅操作纯文本,大量文本写入优先字符流。
六、Properties 配置集合
6.1 概述
java.util.Properties 继承 Hashtable,是专门读取 / 写入配置文件的 Map 集合,键值统一为字符串,内置 IO 读写方法,项目配置文件专用。
6.2 集合操作核心方法
| 方法 | 说明 |
|---|---|
| Object setProperty(String key,String value) | 新增 / 修改键值对 |
| String getProperty(String key) | 根据键查询对应值 |
| Set<String> stringPropertyNames() | 获取全部 key 的集合 |
6.3 IO 读写配置文件方法
| 方法 | 说明 |
|---|---|
| void load(InputStream inStream) | 字节流读取配置文件存入 Properties |
| void load(Reader reader) | 字符流读取配置文件存入 Properties |
| void store(OutputStream out,String comments) | 写出键值对到文件,comments 为文件注释 |
| void store(Writer writer,String comments) | 字符流写出配置文件 |
6.4 小结
Properties 专门操作.properties 配置文件;load 加载、store 持久化保存键值对,是项目读取参数常用方案。
七、Hutool 工具库
7.1 Hutool 介绍
第三方开源 Java 工具包,封装 IO、文件、字符串等高频操作,大幅简化原生 IO 冗余代码,降低开发成本。使用前提:导入 hutool-all 对应 jar 包。
7.2 IOUtil 流工具常用方法
| 方法 | 功能 |
|---|---|
| copy(InputStream in,OutputStream out,int bufferSize) | 字节流一键拷贝文件 |
| copy(Reader reader,Writer writer) | 字符文本拷贝 |
| readLines(Reader reader,Collection<String> collection) | 按行读取文本存入集合 |
| close(Closeable closeables) | 安全批量关闭流,简化资源释放 |
7.3 FileUtil 文件工具常用方法
| 方法 | 功能 |
|---|---|
| touch(filePath) | 自动创建文件,不存在父目录也会生成 |
| mkdir(dirPath) | 创建多级文件夹 |
| copy(srcPath,destPath,isOverride) | 文件 / 文件夹复制,支持覆盖控制 |
| move(srcFile,destDir,isOverride) | 文件移动剪切 |
7.4 小结
Hutool 不属于 JDK 原生 API,需手动导入 jar/Maven 依赖;大幅简化文件拷贝、创建、关流等重复代码,企业开发常用。
八、全文总结
- IO 基础:输入读、输出写;字节流万能,字符流只处理纯文本;
- 字节输出 FileOutputStream:支持追加写入,try-with-resources 自动关流;
- 字节输入 FileInputStream:循环缓冲读取,可实现图片 / 视频任意文件拷贝;
- 字符流 FileReader/FileWriter:纯文本专用,Writer 需要 flush 刷新缓冲区;
- Properties:配置文件专用 Map 集合,load 读取、store 持久化;
- Hutool 第三方工具:封装文件与流操作,简化原生 IO 大量冗余代码。
拓展学习建议
- 分别使用字节流、字符流完成 txt 读写,对比中文处理差异;
- 实现图片、视频拷贝,验证字节流万能特性;
- 手写.properties 配置文件读取案例,模拟项目参数加载;
- 导入 Hutool,使用 IOUtil 一行代码完成文件拷贝。
入门面试高频考点
- 字节流与字符流使用场景区分;
- FileWriter 缓冲区 flush 和 close 区别;
- try-with-resources 语法作用与要求;
- Properties load、store 方法用途;
- 文件拷贝标准实现思路。

878

被折叠的 条评论
为什么被折叠?



