293. Java Stream API - 从 HTTP 源创建 Stream

文章目录

  • [293. Java Stream API - 从 HTTP 源创建 Stream](#293. Java Stream API - 从 HTTP 源创建 Stream)
      • [🎯 核心概念](#🎯 核心概念)
      • [📌 示例:从 HTTP 响应体创建流](#📌 示例:从 HTTP 响应体创建流)
      • [📌 代码解析](#📌 代码解析)
      • [📌 适用场景](#📌 适用场景)
      • [📌 性能考虑](#📌 性能考虑)
      • [📌 总结](#📌 总结)

293. Java Stream API - 从 HTTP 源创建 Stream

🎯 核心概念

Java 11 中,HTTP Client API 引入了一种通过流处理 HTTP 响应体的方法。这种方式可以让你高效地处理大体积数据,而无需一次性将整个响应体加载到内存中。通过这种方式,你可以像处理文件一样逐行读取 HTTP 响应体。

📌 示例:从 HTTP 响应体创建流

假设你想要处理 《双城记》(A Tale of Two Cities 这本书的文本,书本内容可以通过 古腾堡计划 在线获取。我们需要从中去掉头部和尾部信息,只提取正文部分。

以下是从 HTTP 源获取文本并创建流的完整示例:

java 复制代码
// URI 指向文件地址
URI uri = URI.create("https://www.gutenberg.org/files/98/98-0.txt");

// 创建 HTTP 请求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(uri).build();

// 发送请求并获取响应体作为行流(Stream<String>)
HttpResponse<Stream<String>> response = client.send(request, HttpResponse.BodyHandlers.ofLines());

List<String> lines;
try (Stream<String> stream = response.body()) {
    lines = stream
              .dropWhile(line -> !line.equals("A TALE OF TWO CITIES"))  // 跳过头部信息
              .takeWhile(line -> !line.equals("*** END OF THE PROJECT GUTENBERG EBOOK A TALE OF TWO CITIES ***"))  // 跳过尾部信息
              .collect(Collectors.toList());  // 将正文部分收集到列表中
}

System.out.println("# lines = " + lines.size());  // 输出处理后的行数

🧾 输出结果:

java 复制代码
# lines = 15904

📌 代码解析

  1. 创建 URIHTTP 请求 :首先,我们使用 URI.create() 方法创建指向文件的 URI,然后用 HttpClient.newHttpClient() 创建 HTTP 客户端,并构建一个 HTTP 请求。
  2. 发送请求并获取响应体 :使用 client.send(request, HttpResponse.BodyHandlers.ofLines()) 发送请求,并通过 BodyHandlers.ofLines() 方法获取 HTTP 响应体的行流。这种方式返回的是 Stream<String>,意味着你可以像处理普通的文本文件一样处理响应体。
  3. 流操作
    • dropWhile():跳过文件中直到找到《双城记》标题的部分,排除掉头部信息。
    • takeWhile():继续获取直到找到结尾的标记为止,排除掉尾部信息。
    • collect(Collectors.toList()):将结果收集到列表中(在这个示例中,我们将正文的每一行保存为列表项)。
  4. 高效内存管理 :由于我们使用了 Stream,响应体的内容是逐行处理的,这样可以避免将整个文本加载到内存中,对于处理大文件非常有利。

📌 适用场景

这种从 HTTP 响应体创建流的方式非常适用于以下场景:

  • 大文件的高效处理:当你需要从服务器下载并处理大文本文件(如日志文件、大型书籍等)时,逐行读取数据比将整个文件加载到内存中更加节省内存,避免了内存溢出的风险。
  • 流式处理:适用于实时处理和流式数据的场景,尤其是在处理大规模响应数据时(例如日志分析或实时数据流)。

📌 性能考虑

  • 内存效率:与直接将响应体存储到内存中的做法相比,逐行处理可以极大地减少内存消耗,尤其在处理大文件时尤为重要。
  • 延迟控制:通过流处理,可以更灵活地控制数据的处理节奏。例如,你不需要一次性加载所有数据,可以随时对流中的数据进行过滤、转换等操作。

📌 总结

  • HTTP Client API (自 JDK 11)为我们提供了处理 HTTP 响应的强大功能。通过 HttpResponse.BodyHandlers.ofLines(),我们可以创建一个逐行处理响应体的流。
  • 这种方式非常适合于需要从网络获取并处理大量数据的场景,特别是在内存受限的情况下,能够提高应用程序的性能和稳定性。
  • 我们演示了如何去掉文件的头部和尾部信息,仅保留正文内容,进行流式处理。
相关推荐
_F_y9 分钟前
C++重点知识总结
java·jvm·c++
打工的小王10 分钟前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
毕设源码-赖学姐11 分钟前
【开题答辩全过程】以 高校体育场馆管理系统为例,包含答辩的问题和答案
java·spring boot
我真会写代码13 分钟前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
vx_Biye_Design13 分钟前
【关注可免费领取源码】房屋出租系统的设计与实现--毕设附源码40805
java·spring boot·spring·spring cloud·servlet·eclipse·课程设计
java干货18 分钟前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
_F_y18 分钟前
C语言重点知识总结(含KMP详细讲解)
c语言·开发语言
DN金猿19 分钟前
接口路径正确,请求接口却提示404
java·tomcat
毕设源码-郭学长19 分钟前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
无小道42 分钟前
Qt——常用控件
开发语言·qt