1. 使用原生 Java

✅ 最直接的方式就是使用 JDK 自带的 FileReader,无需引入第三方依赖,简单粗暴。

需要注意的是:FileReader 使用平台默认字符编码,在跨平台场景下容易踩坑(比如 Windows 和 Linux 编码不一致导致乱码)。因此建议明确指定编码,但 FileReader 不支持传入 Charset,所以如果需要指定编码,应使用 InputStreamReader 包装 FileInputStream

示例代码如下:

@Test
public void givenUsingPlainJava_whenConvertingFileIntoReader_thenCorrect() 
    throws IOException {
    File initialFile = new File("src/test/resources/initialFile.txt");
    initialFile.createNewFile();
    Reader targetReader = new FileReader(initialFile);
    targetReader.close();
}

⚠️ 注意:createNewFile() 只有在文件不存在时才创建,否则返回 false。测试前确保路径目录存在,否则会抛出异常。

如果你想控制字符编码,推荐写法:

Reader reader = new InputStreamReader(
    new FileInputStream(initialFile), 
    StandardCharsets.UTF_8
);

2. 使用 Guava

✅ Guava 提供了更简洁、功能更强的 IO 工具类 Files,可以指定字符编码,避免平台默认编码带来的问题。

Files.newReader() 方法允许你传入 Charset,非常灵活。此外,com.google.common.io.Files.touch() 相当于确保文件存在(不存在则创建,包括父目录)。

示例:

@Test
public void givenUsingGuava_whenConvertingFileIntoReader_thenCorrect() throws 
    IOException {
    File initialFile = new File("src/test/resources/initialFile.txt");
    com.google.common.io.Files.touch(initialFile);
    Reader targetReader = Files.newReader(initialFile, Charset.defaultCharset());
    targetReader.close();
}

📌 小贴士:

  • Charset.defaultCharset() 仍然依赖系统默认编码,生产环境建议显式使用 StandardCharsets.UTF_8
  • Guava 的 Files 类位于 com.google.common.io.Files,别和 JDK 7+ 的 java.nio.file.Files 搞混了

推荐改进版本:

Reader targetReader = Files.newReader(initialFile, StandardCharsets.UTF_8);

3. 使用 Apache Commons IO

❌ 这种方式相对绕路,但展示了另一种思路:先读取文件为字节数组,再转换成字符串,最后包装为 Reader

Commons IO 提供了 FileUtils.readFileToByteArray() 快速读取整个文件内容到内存。适用于小文件,大文件慎用,容易 OOM

关键点是使用 CharSequenceReader —— 它是 Commons IO 提供的一个将字符串或字符序列包装成 Reader 的工具类。

示例代码:

@Test
public void givenUsingCommonsIO_whenConvertingFileIntoReader_thenCorrect() 
    throws IOException {
    File initialFile = new File("src/test/resources/initialFile.txt");
    FileUtils.touch(initialFile);
    FileUtils.write(initialFile, "With Commons IO", StandardCharsets.UTF_8);
    byte[] buffer = FileUtils.readFileToByteArray(initialFile);
    Reader targetReader = new CharSequenceReader(new String(buffer, StandardCharsets.UTF_8));
    targetReader.close();
}

📌 说明:

  • FileUtils.write() 支持直接指定编码,比原生更友好
  • new String(byte[], Charset) 必须指定编码,否则又回到平台默认编码的老问题
  • CharSequenceReader 来自 org.apache.commons.io.input.CharSequenceReader

⚠️ 警告:这种方式将整个文件加载进内存,不适合处理大文件。对于大文件,应使用流式处理(streaming),避免内存溢出。


✅ 总结对比

方式 优点 缺点 推荐指数
原生 Java 无需依赖,简单直接 无法指定编码(FileReader) ⭐⭐☆
Guava API 简洁,支持编码,工具强大 需引入 Guava,体量较大 ⭐⭐⭐⭐
Commons IO 功能丰富,易用 转换路径绕,内存占用高 ⭐⭐⭐☆

💡 最佳实践建议

  • **优先使用 Guava 的 Files.newReader(file, charset)**:语义清晰、编码可控、代码简洁
  • 如果项目已引入 Spring,则可考虑 FileCopyUtilsStreamUtils
  • 处理完 Reader 后务必关闭资源,推荐使用 try-with-resources:
try (Reader reader = Files.newReader(initialFile, StandardCharsets.UTF_8)) {
    // 读取逻辑
} // 自动关闭
  • 对于大文件,始终使用流式处理,避免一次性加载到内存

作者邮箱:dev@example.com
原文链接:https://www.baeldung.com/java-file-to-reader
系列教程:Java – 回到基础


原始标题:Java - File to Reader | Baeldung