2025/7/15——java学习总结
Java IO、Stream、异常与 File 全体系总结:从基础到进阶的完整突破
一、核心知识深耕:四大模块的体系与底层逻辑
(一)IO 流:数据传输的基础通道
体系架构与核心分类
- 按流向:输入流(
InputStream
/Reader
)、输出流(OutputStream
/Writer
)。 - 按数据单位:
- 字节流:处理所有数据(二进制、文本),核心类
FileInputStream
/FileOutputStream
。 - 字符流:处理文本数据(自动编码转换),核心类
FileReader
/FileWriter
、InputStreamReader
(指定编码)。
- 字节流:处理所有数据(二进制、文本),核心类
- 按角色:
- 节点流:直接操作数据源(如
FileInputStream
)。 - 处理流:增强节点流功能(如
BufferedInputStream
加缓冲、ObjectInputStream
序列化)。
- 节点流:直接操作数据源(如
- 按流向:输入流(
核心方法与特性
- 字节流:
read()
/write()
(单字节或字节数组)。 - 字符流:
read()
/write()
(字符或字符数组)、BufferedReader.readLine()
(按行读取)。 - 资源管理:实现
AutoCloseable
接口,支持try-with-resources
自动关闭。
- 字节流:
(二)Java 8 Stream:集合数据的高效处理
核心概念与特性
- 定义:基于数据源(集合、数组)的元素序列,支持声明式操作(过滤、映射、聚合等)。
- 特性:
- 惰性执行:中间操作(如
filter
)仅记录逻辑,终端操作(如collect
)才触发执行。 - 一次性消费:流只能遍历一次,再次使用需重新创建。
- 并行处理:通过
parallelStream()
实现多线程并行操作。
- 惰性执行:中间操作(如
操作分类
- 中间操作(返回新流):
- 过滤:
filter(Predicate)
- 映射:
map(Function)
、flatMap(Function)
(将流扁平化) - 排序:
sorted()
、sorted(Comparator)
- 过滤:
- 终端操作(返回非流结果):
- 聚合:
collect(Collector)
(如Collectors.toList()
)、count()
、max(Comparator)
- 遍历:
forEach(Consumer)
- 匹配:
anyMatch(Predicate)
、allMatch(Predicate)
- 聚合:
- 中间操作(返回新流):
(三)异常处理:程序容错的核心机制
异常体系结构
- 顶层父类:
Throwable
,分为:Error
:虚拟机错误(如OutOfMemoryError
),无法处理,需避免。Exception
:程序可处理的异常,分为:- 编译时异常(Checked):如
IOException
、ClassNotFoundException
,必须显式处理。 - 运行时异常(Unchecked):如
NullPointerException
、IndexOutOfBoundsException
,继承自RuntimeException
,可选择处理。
- 编译时异常(Checked):如
- 顶层父类:
异常处理方式
- 捕获:
try-catch-finally
块,finally
用于释放资源(如流关闭)。 - 声明抛出:
throws
关键字,将异常交给上层处理。 - 自定义异常:继承
Exception
或RuntimeException
,封装业务异常信息。
- 捕获:
(四)File 类:文件系统的抽象表示
核心功能
- 表示文件或目录的路径(不直接操作文件内容)。
- 关键方法:
- 路径操作:
getAbsolutePath()
、getPath()
、getName()
。 - 存在性判断:
exists()
、isFile()
、isDirectory()
。 - 创建 / 删除:
createNewFile()
、mkdirs()
(多级目录)、delete()
。 - 列表获取:
list()
(文件名数组)、listFiles()
(File 对象数组)。
- 路径操作:
路径特性
- 绝对路径:从根目录开始(如
C:/test/file.txt
)。 - 相对路径:相对于当前工作目录(如
src/main/java
)。 - 跨平台兼容:通过
File.separator
替代硬编码的/
或\
。
- 绝对路径:从根目录开始(如
二、实践突破:四大模块的场景化应用
(一)IO 流实战:文件处理与编码控制
1. 大文件拷贝(缓冲流优化)
java
public class LargeFileCopy {public static void main(String[] args) throws IOException {long start = System.currentTimeMillis();// 缓冲流 + 大字节数组提升效率try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.iso"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("target.iso"))) {byte[] buffer = new byte[8192 * 4]; // 32KB缓冲区int len;while ((len = bis.read(buffer)) != -1) {bos.write(buffer, 0, len);}}System.out.println("拷贝完成,耗时:" + (System.currentTimeMillis() - start) + "ms");}
}
2. 字符流处理编码(避免乱码)
java
public class EncodingHandler {public static void main(String[] args) {String content = "Java IO流与编码处理";String path = "encoding_test.txt";// 用UTF-8编码写入try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(path), StandardCharsets.UTF_8);BufferedWriter bw = new BufferedWriter(osw)) {bw.write(content);} catch (IOException e) {e.printStackTrace();}// 用UTF-8解码读取try (InputStreamReader isr = new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8);BufferedReader br = new BufferedReader(isr)) {String line;while ((line = br.readLine()) != null) {System.out.println("读取内容:" + line);}} catch (IOException e) {e.printStackTrace();}}
}
(二)Stream API 实战:集合数据处理
1. 复杂对象集合处理
java
class User {private String name;private int age;private String city;// 构造器、getter省略
}public class StreamDemo {public static void main(String[] args) {List<User> users = Arrays.asList(new User("张三", 25, "北京"),new User("李四", 30, "上海"),new User("王五", 28, "北京"),new User("赵六", 35, "广州"));// 需求:筛选北京的用户,按年龄排序,提取姓名并拼接String result = users.stream().filter(u -> "北京".equals(u.getCity())) // 过滤北京用户.sorted(Comparator.comparingInt(User::getAge)) // 按年龄排序.map(User::getName) // 提取姓名.collect(Collectors.joining(",", "北京用户:", "。")); // 拼接System.out.println(result); // 输出:北京用户:张三,王五。}
}
2. 并行流处理大数据量
java
public class ParallelStreamDemo {public static void main(String[] args) {// 生成1000万个随机数List<Integer> numbers = new ArrayList<>(10_000_000);Random random = new Random();for (int i = 0; i < 10_000_000; i++) {numbers.add(random.nextInt(1000));}// 并行流计算偶数之和long start = System.currentTimeMillis();long sum = numbers.parallelStream().filter(n -> n % 2 == 0).mapToLong(Integer::longValue).sum();System.out.println("偶数和:" + sum + ",耗时:" + (System.currentTimeMillis() - start) + "ms");}
}
(三)异常处理实战:优雅的错误控制
1. 多异常捕获与资源自动关闭
java
public class ExceptionHandling {public static void readFile(String path) {// try-with-resources自动关闭资源,多异常用|分隔try (BufferedReader br = new BufferedReader(new FileReader(path))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (FileNotFoundException e) {System.err.println("文件不存在:" + path);} catch (IOException e) {System.err.println("读取失败:" + e.getMessage());}}
}
2. 自定义异常与异常链
java
// 自定义业务异常
class InsufficientFundsException extends Exception {public InsufficientFundsException(String message) {super(message);}
}public class CustomExceptionDemo {public static void withdraw(double amount) throws InsufficientFundsException {double balance = 1000;if (amount > balance) {// 包装原始异常为自定义异常throw new InsufficientFundsException("余额不足,当前余额:" + balance);}}public static void main(String[] args) {try {withdraw(1500);} catch (InsufficientFundsException e) {e.printStackTrace();// 处理业务异常}}
}
(四)File 类实战:文件系统操作
1. 递归遍历目录并统计文件类型
java
public class FileTraversal {public static void main(String[] args) {File dir = new File("D:/project");Map<String, Integer> typeCount = new HashMap<>();traverse(dir, typeCount);// 输出统计结果typeCount.forEach((type, count) -> System.out.println(type + "文件:" + count + "个"));}private static void traverse(File file, Map<String, Integer> typeCount) {if (file.isDirectory()) {File[] children = file.listFiles();if (children != null) { // 避免空指针for (File child : children) {traverse(child, typeCount);}}} else {// 获取文件后缀String name = file.getName();int dotIndex = name.lastIndexOf('.');String type = (dotIndex == -1) ? "无后缀" : name.substring(dotIndex);// 更新计数typeCount.put(type, typeCount.getOrDefault(type, 0) + 1);}}
}
2. 文件批量重命名
java
public class FileRename {public static void main(String[] args) {File dir = new File("D:/photos");File[] files = dir.listFiles(f -> f.isFile() && f.getName().endsWith(".jpg"));if (files != null) {for (int i = 0; i < files.length; i++) {File oldFile = files[i];String newName = "travel_" + (i + 1) + ".jpg";File newFile = new File(dir, newName);if (oldFile.renameTo(newFile)) {System.out.println("重命名成功:" + newName);}}}}
}
三、底层原理:四大模块的运行机制
(一)IO 流的底层实现
字节流与系统调用:
FileInputStream.read()
最终调用 native 方法(如read0()
),通过操作系统内核读取文件数据。- 缓冲流(
BufferedInputStream
)内部维护字节数组缓冲区,减少系统调用次数(一次读取 8KB,而非单字节)。
字符流的编码转换:
InputStreamReader
使用CharsetDecoder
将字节按指定编码(如 UTF-8)解码为字符。- 多字节字符(如中文)需连续读取完整字节序列,否则会产生乱码。
(二)Stream API 的执行原理
惰性求值机制:
- 中间操作(如
filter
)仅构建操作管道,不实际执行。 - 终端操作(如
collect
)触发整个管道执行,采用流水线方式处理元素。
- 中间操作(如
并行流实现:
- 基于
Fork/Join
框架,将数据源拆分为多个子任务,通过多线程并行处理。 - 适用于 CPU 密集型任务,IO 密集型任务并行优势不明显。
- 基于
(三)异常处理的底层机制
异常表与栈跟踪:
- 编译期生成异常表,记录
try-catch
块的范围和处理的异常类型。 - 异常抛出时,JVM 通过异常表查找匹配的
catch
块,若未找到则终止线程并打印栈跟踪(printStackTrace()
)。
- 编译期生成异常表,记录
try-with-resources
原理:- 编译器自动生成
finally
块,调用资源的close()
方法,确保资源释放。 - 多个资源按声明逆序关闭(先关最后声明的资源)。
- 编译器自动生成
(四)File 类与文件系统交互
路径解析:
- 依赖操作系统的文件系统接口,将抽象路径转换为系统实际路径。
- 相对路径解析基于
user.dir
系统属性(程序运行目录)。
文件操作的原子性:
renameTo()
方法在不同文件系统间可能非原子操作,可能导致文件丢失。- 目录删除(
delete()
)仅支持空目录,非空目录需递归删除子文件。
四、总结与展望:从整合到进阶
今日突破
- 知识整合:贯通 IO 流(数据传输)、Stream(数据处理)、异常(容错机制)、File(文件系统)四大模块,形成完整的数据处理链路。
- 实践能力:掌握大文件高效处理、编码控制、集合流处理优化、异常优雅处理、文件系统批量操作等实战技能。
- 底层认知:理解 IO 流的系统调用、Stream 的惰性执行、异常表机制、File 与操作系统交互等底层逻辑。
后续进阶方向
NIO 与异步 IO:
- 学习
java.nio
包的通道(Channel
)、缓冲区(Buffer
)、选择器(Selector
),掌握非阻塞 IO 模型。 - 异步 IO(
AsynchronousFileChannel
)提升高并发场景下的性能。
- 学习
Stream 高级应用:
- 自定义收集器(
Collector
)处理复杂聚合逻辑。 - 流的并行策略优化(如
Spliterator
自定义拆分)。
- 自定义收集器(
异常处理模式:
- 学习异常转译(将底层异常转为业务异常)、异常重试机制、全局异常处理器(如 Spring 的
@ControllerAdvice
)。
- 学习异常转译(将底层异常转为业务异常)、异常重试机制、全局异常处理器(如 Spring 的
文件系统高级操作:
- 学习
java.nio.file
包(Path
、Files
、FileSystem
),支持更丰富的文件操作(如文件属性、符号链接)。
- 学习
通过四大模块的协同学习,不仅能应对日常开发中的数据处理需求,更能深入理解 Java 的 IO 模型、函数式编程、容错设计等核心思想,为高性能、高可靠性的 Java 应用开发奠定基础 ✨。