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 可以使文件处理的代码更加简洁、可读和可维护。
相关推荐
涡能增压发动积21 小时前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
Wenweno0o21 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
于慨21 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
石小石Orz21 小时前
油猴脚本实现生产环境加载本地qiankun子应用
前端·架构
swg32132121 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
从前慢丶21 小时前
前端交互规范(Web 端)
前端
tyung21 小时前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald21 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
CHU72903521 小时前
便捷约玩,沉浸推理:线上剧本杀APP功能版块设计详解
前端·小程序
GISer_Jing21 小时前
Page-agent MCP结构
前端·人工智能