java中的异常与IO(异常重点)

Java 异常 + IO 完整知识点

一、Java 异常体系

  1. 异常分类结构
    Throwable
    ├─ Error 错误(系统级,程序无法处理,不用捕获)
    │ 如:OutOfMemoryError、StackOverflowError
    └─ Exception 异常(程序可处理)
    ├─ 受检异常 CheckedException(编译强制捕获/抛出)
    │ IO、SQL、文件、类不存在等
    └─ 非受检异常 RuntimeException(运行时才报错,编译不强制处理)
    空指针、数组越界、类型转换、算术除0
  2. 异常处理关键字:try-catch-finally、throws、throw

(1)try-catch-finally

• try:放可能出错的代码

• catch:捕获对应异常,处理逻辑

• finally:无论是否异常、是否return,一定会执行,IO流关闭写在这里
public void test() {
try {
int a = 1 / 0;
} catch (ArithmeticException e) {
System.out.println("除零异常:" + e.getMessage());
e.printStackTrace(); // 打印完整堆栈
} finally {
System.out.println("必然执行,用于关闭IO资源");
}
}
(2)throws 声明抛出

方法自己不处理,把异常抛给调用者,只用于受检异常
// IO异常是受检异常,必须throws或try-catch
public void readFile() throws IOException {
FileReader fr = new FileReader("test.txt");
}
(3)throw 手动抛出异常

主动制造异常,多用于参数校验
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
(4)try-with-resources(Java7 推荐,IO必备)

实现 AutoCloseable 的资源(IO流),写完自动关闭,替代finally手动关流,无需手动close
try (FileReader fr = new FileReader("a.txt")) {
char c = (char) fr.read();
} catch (IOException e) {
e.printStackTrace();
}
// 离开try块自动调用fr.close(),不用写finally
3. 自定义异常

继承 Exception(受检)/RuntimeException(非受检)
// 自定义受检异常
class FileEmptyException extends Exception {
public FileEmptyException(String msg) {
super(msg);
}
}
二、Java IO 流体系

  1. 四大基类(分字节流/字符流)
    分类 输入(读) 输出(写) 适用场景
    字节流(二进制) InputStream OutputStream 图片、视频、压缩包、任意文件
    字符流(文本) Reader Writer txt、java、md 纯文本

核心区别

• 字节流:操作byte,不带缓冲区,读写文件直接操作磁盘

• 字符流:操作char,自带缓冲区,不flush/close会丢失数据

  1. 常用IO子类

字节流

  1. FileInputStream / FileOutputStream:文件原始字节读写

  2. BufferedInputStream / BufferedOutputStream:缓冲包装,提速

  3. ObjectInputStream / ObjectOutputStream:对象序列化读写

字符流

  1. FileReader / FileWriter:文件文本读写

  2. BufferedReader / BufferedWriter:带行缓冲,readLine()按行读

  3. InputStreamReader / OutputStreamWriter:转换流(字节→字符,指定编码)

  4. 基础文件读写代码示例

示例1:字符缓冲读取文本(BufferedReader)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class IoDemo {
public static void main(String[] args) {
// try-with-resources自动关流
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
示例2:字节流复制文件(图片/视频通用)
try (FileInputStream fis = new FileInputStream("src.jpg");
FileOutputStream fos = new FileOutputStream("dest.jpg")) {

byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
示例3:转换流解决中文乱码(指定UTF-8)
// 字节流转字符流,手动设置编码,避免系统默认编码乱码
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("utf8.txt"), "UTF-8")
)) {
String s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
4. IO核心注意事项(结合异常)

  1. IO操作全部抛出 IOException(受检异常),必须 try-catch 或 throws

  2. 资源必须关闭:

• Java7+:优先 try-with-resources,自动关闭,代码简洁安全

• Java6及以下:必须在 finally 中手动调用 close(),且close也要捕获异常

  1. 字符流有缓冲区:写入后不调用 flush()/close(),数据留在内存,文件为空

  2. 文件输出流 FileOutputStream("a.txt") 会覆盖原文件;追加使用 new FileOutputStream("a.txt", true)

  3. File 文件类(文件/目录操作,不属于流)

只操作文件元信息(创建、删除、判断是否存在、遍历文件夹),不读写内容
File file = new File("test.txt");
System.out.println(file.exists()); // 是否存在
file.createNewFile(); // 创建空文件,抛IOException
File dir = new File("folder");
dir.mkdirs(); // 创建多级文件夹
三、异常 + IO 综合高频考点

  1. 为什么IO异常是受检异常?
    IO操作依赖外部磁盘文件,极易出现文件不存在、权限不足、文件损坏等外部错误,编译器强制开发者处理,避免程序无声崩溃。

  2. finally 和 try-with-resources 怎么选?
    Java7及以后一律用try-with-resources,代码更少、不会漏关流;finally适合不实现AutoCloseable的自定义资源。

  3. 字符流和字节流怎么选?

• 纯文本文件:字符流(便捷,支持按行读取)

• 图片、视频、exe、压缩包:只能字节流,字符流会损坏二进制数据

  1. 缓冲区丢失数据问题
    BufferedWriter/FileWriter写入内容后程序直接退出,不close/flush,缓冲区数据未刷入磁盘,文件无内容;close会自动执行flush。

  2. 异常链:捕获IO异常后可以包装自定义异常抛出
    try {
    // 文件读取
    } catch (IOException e) {
    throw new FileEmptyException("文件读取失败", e); // 保留原始异常堆栈
    }
    四、易错题总结

  3. 忘记处理IO异常,编译直接报错(受检异常)

  4. 读写二进制图片使用FileReader,导致文件损坏

  5. 字符流写完未关闭,文件空白

  6. 不使用缓冲流,大文件读写速度极慢

  7. 没有用try-with-resources,忘记关闭流,造成文件资源泄漏

  8. 转换流不指定编码,Windows默认GBK读取UTF-8文件出现中文乱码

posted @ 2026-06-23 16:30  人青是个小卷毛  阅读(10)  评论(0)    收藏  举报