本文详解为何 BufferedReader.readLine() 循环结束后返回 null,并提供使用 StringJoiner、try-with-resources 和 Files.readAllLines() 的专业解决方案,确保方法稳定返回完整文件内容。
本文详解为何 `bufferedreader.readline()` 循环结束后返回 `null`,并提供使用 `stringjoiner`、`try-with-resources` 和 `files.readalllines()` 的专业解决方案,确保方法稳定返回完整文件内容。
问题核心在于对 BufferedReader.readLine() 行为的误解:该方法在
到达文件末尾时返回 null
,而您的 while (fileContents != null) 循环正是依赖此特性退出——因此循环终止后,fileContents 必然为 null,直接 return fileContents 自然返回 null,而非预期的全部内容。
要正确拼接所有行并返回完整字符串,需在循环中持续累积内容,而非反复覆盖同一变量。以下是推荐的三种实现方式,均采用现代 Java 最佳实践:
✅ 推荐方案一:StringJoiner + try-with-resources(兼顾可读性与资源安全)
✅
优势
:自动管理资源(无需手动 close())、线程安全、语义清晰;System.lineSeparator() 保证跨平台换行符兼容。
✅ 推荐方案二:Files.readAllLines()(最简洁,Java 7+)
✅
优势
:代码极简、内置异常传播、自动处理编码(默认 UTF-8);若需自定义编码,可用 Files.readAllLines(path, StandardCharsets.UTF_8)。
⚠️ 注意事项与避坑指南
不要吞掉异常
:原代码中 e.printStackTrace() 仅打印日志,却返回 null,调用方无法区分“文件不存在”与“读取成功但内容为空”。应声明 throws IOException,由上层统一处理错误。
避免手动 close()
:使用 try-with-resources(如方案一)确保 BufferedReader 在任何情况下(包括异常)都被关闭,防止资源泄漏。
null 不是有效业务返回值
:返回 null 容易引发后续 NullPointerException。若必须返回默认值,建议用空字符串 "" 或抛出明确异常(如 FileNotFoundException)。
编码问题
:FileReader 使用平台默认编码,可能导致中文乱码。生产环境强烈建议改用 Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)。
综上,选择方案一或二均可彻底解决 null 返回问题。对于新项目,优先采用 Files.readAllLines();若需精细控制(如大文件流式处理),则选用 BufferedReader + StringJoiner 组合。
import java.io.*;
import java.util.StringJoiner;
public static String readTestResults(String fileName) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
StringJoiner joiner = new StringJoiner(System.lineSeparator());
String line;
while ((line = reader.readLine()) != null) {
joiner.add(line); // 逐行添加,自动处理换行分隔
}
return joiner.toString(); // 返回完整内容(不含末尾多余换行)
}
}import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public static String readTestResults(String fileName) throws IOException {
List lines = Files.readAllLines(Paths.get(fileName));
return String.join(System.lineSeparator(), lines);
} 