411. Java 文件操作基础 - 从网络到本地:读取文本资源的两种方式与最佳实践
🎯 目标
- 如何通过
HttpClient API从互联网读取文本资源 - 如何使用
Files API从本地文件读取 - 如何正确处理 异常 和 资源关闭
- 如何将
InputStream转换为Reader以便逐行读取文本
1️⃣ 在线读取(使用 HttpClient)
在有网络连接时,可以直接访问 Gutenberg Project 提供的在线资源。
示例代码:在线读取十四行诗
JAVA8
import java.io.*;
import java.net.*;
public class Demo {
public static void main(String[] args) {
String urlStr = "https://www.gutenberg.org/cache/epub/1041/pg1041.txt";
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
int responseCode = connection.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK) {
System.err.println("HTTP request failed with code: " + responseCode);
return;
}
// 读取响应内容,打印前14行
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
String line;
int count = 0;
while ((line = reader.readLine()) != null && count < 14) {
System.out.println(line);
count++;
}
}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
JAVA11
import java.io.*;
import java.net.URI;
import java.net.http.*;
public class ReadSonnetsOnline {
public static void main(String[] args) {
URI sonnetsURI = URI.create("https://www.gutenberg.org/cache/epub/1041/pg1041.txt");
HttpRequest request = HttpRequest.newBuilder(sonnetsURI)
.GET()
.build();
HttpClient client = HttpClient.newHttpClient();
try {
HttpResponse<InputStream> response =
client.send(request, HttpResponse.BodyHandlers.ofInputStream());
// 将 InputStream 转换为 Reader,便于逐行读取
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body()))) {
String line;
int count = 0;
while ((line = reader.readLine()) != null && count < 14) {
System.out.println(line);
count++;
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
✅ 要点讲解:
HttpClient是 Java 11 引入的现代 HTTP 客户端,替代老旧的HttpURLConnection。HttpResponse.BodyHandlers.ofInputStream()获取原始字节流,然后用InputStreamReader转成字符流。- 使用
try-with-resources确保流在使用后关闭。 - 示例中只输出前 14 行,避免刷屏。
2️⃣ 本地读取(使用 Files API)
如果提前下载 pg1041.txt 文件,可以直接用 NIO 的 Files 工具类 来读取。
示例代码:本地读取十四行诗
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.*;
public class ReadSonnetsLocal {
public static void main(String[] args) {
Path path = Path.of("files/sonnets.txt");
try (BufferedReader reader = Files.newBufferedReader(path)) {
String line;
int count = 0;
while ((line = reader.readLine()) != null && count < 14) {
System.out.println(line);
count++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
✅ 要点讲解:
Files.newBufferedReader(path)直接返回一个BufferedReader,方便逐行读取文本。- 仍然使用
try-with-resources来自动关闭资源。 - 整体写法比
HttpClient更简单,因为本地文件访问比网络请求更可靠。
3️⃣ 两种方式对比
| 方式 | 使用场景 | 优点 | 缺点 |
|---|---|---|---|
| HttpClient | 在线读取 | 不需手动下载,随时获取最新内容 | 依赖网络,速度受限 |
| Files API | 本地读取 | 高效、稳定,无需网络 | 需要事先下载文件 |
4️⃣ 扩展思考
-
如果文件非常大,是否应该一次性读取? 👉 答案:不要。应使用 逐行流式读取,避免内存溢出。
-
如果要处理文本编码(如 UTF-8 / ISO-8859-1)怎么办? 👉 可以在
InputStreamReader或Files.newBufferedReader里指定编码:new InputStreamReader(response.body(), StandardCharsets.UTF_8); Files.newBufferedReader(path, StandardCharsets.UTF_8);