290. Java Stream API - 从文本文件的行创建 Stream

290. Java Stream API - 从文本文件的行创建 Stream

🎯 核心概念

在 Java 中,能够直接打开一个文本文件并对其进行流式处理是一种非常强大的模式。

  • 传统方式: Java I/O API 提供了通过 BufferedReader.readLine() 方法逐行读取文件内容的方式。这需要使用循环逐行读取文件并处理每一行。
  • Stream API 的优势: 使用 Stream API,你可以更简洁、更具可维护性地处理文件内容,代码可读性更高。

📌 创建流的两种模式

  1. 基于现有的 BufferedReader 如果你需要重构已经使用 BufferedReader 的代码,可以使用 BufferedReader.lines() 方法来获取一个行流。
  2. 基于新代码: 如果你是编写新代码来处理文件内容,建议使用 Files.lines() 方法。这个方法接收一个 Path 参数,并且有一个重载版本,允许你指定字符集(Charset),以支持读取非 UTF-8 编码的文件。

📌 文件流的关闭

重要概念: 处理文件时,文件资源必须在不再需要时关闭,以释放系统资源。幸运的是,Stream 接口实现了 AutoCloseable 接口,这意味着你可以通过 try-with-resources 语法自动关闭文件流。

这样,Stream 本身作为一个资源,可以在你使用完后自动调用 close() 方法进行关闭。这对于 I/O 操作至关重要,因为没有正确关闭文件流,可能会导致资源泄漏。


📌 示例:统计日志文件中的警告数量

以下是一个通过 Stream API 统计日志文件中警告数量的示例。由于某些环境限制,你无法直接在浏览器中运行此代码。你可以将其复制到本地的 IDE 中,并调整文件路径来运行。

java 复制代码
Path log = Path.of("/tmp/debug.log");  // 根据本地文件路径调整

try (Stream<String> lines = Files.lines(log)) {  // 使用 try-with-resources 确保文件流关闭
    long warnings = 
        lines.filter(line -> line.contains("WARNING"))  // 过滤出包含 "WARNING" 的行
             .count();  // 统计行数
    System.out.println("Number of warnings = " + warnings);  // 输出结果
} catch (IOException e) {  // 处理可能的异常
   // 这里可以处理异常,比如打印日志等
   e.printStackTrace();
}

🧾 输出示例:

java 复制代码
Number of warnings = 15

🧠 讲解:

  1. Files.lines(log) :此方法返回一个包含文件中所有行的 Stream<String>。你可以对这个流执行操作。
  2. lines.filter(line -> line.contains("WARNING")):过滤出所有包含 "WARNING" 关键字的行。
  3. count():统计符合条件的行数。
  4. try-with-resourcesStream 是一个资源,try-with-resources 会自动在结束时关闭它,避免资源泄露。

📚 小贴士

  • 字符集处理: 如果文件是非 UTF-8 编码,你可以使用 Files.lines(path, Charset) 来读取该文件。
  • 异常处理: 处理文件流时,通常会遇到 IOException,因此需要进行异常捕获和处理。

🎯 小测验(课堂互动)

问题: 如果在文件中查找 "ERROR" 关键字,如何修改过滤条件?

✅ A. lines.filter(line -> line.contains("ERROR")) ❌ B. lines.filter(line -> line.contains("WARNING"))正确答案: A


📌 总结

  • Files.lines()BufferedReader.lines() 都是处理文本文件行的优秀方式。
  • try-with-resources 是处理 I/O 流的最佳实践,它确保了文件流的正确关闭。
  • 使用 Stream API 可以使文件处理的代码更加简洁、可读和可维护。
相关推荐
林小帅27 分钟前
【笔记】OpenClaw 架构浅析
前端·agent
林小帅1 小时前
【笔记】OpenClaw 生态系统的多语言实现对比分析
前端·agent
程序猿的程1 小时前
开源一个 React 股票 K 线图组件,传个股票代码就能画图
前端·javascript
不爱说话郭德纲2 小时前
告别漫长的HbuilderX云打包排队!uni-app x 安卓本地打包保姆级教程(附白屏、包体积过大排坑指南)
android·前端·uni-app
唐叔在学习2 小时前
[前端特效] 左滑显示按钮的实现介绍
前端·javascript
点光2 小时前
使用Sentinel作为Spring Boot应用限流组件
后端
用户5282290301802 小时前
【学习笔记】ECMAScript 词法环境全解析
前端
青青家的小灰灰2 小时前
React 架构进阶:自定义 Hooks 的高级设计模式与最佳实践
前端·react.js·前端框架
Angelial3 小时前
Vite 性能瓶颈排查标准流程
前端
不要秃头啊3 小时前
别再谈提效了:AI 时代的开发范式本质变了
前端·后端·程序员