1. 概述

本文将介绍如何将 File 对象转换为 InputStream——分别使用 原生 JavaGuavaApache Commons IO 三种方式实现。

这类操作在文件处理、IO 转换中非常常见,属于基础但高频的“踩坑点”。掌握多种写法,能让你在不同项目环境下游刃有余。

本文是 Baeldung 系列教程 《Java – 回归基础》 的一部分。

2. 使用原生 Java 转换

Java 自带的 java.io 包提供了多种将文件转为输入流的方式。以下是几种典型用法。

2.1. FileInputStream

最直接、最常用的方式就是 FileInputStream,简单粗暴,适合大多数场景。

✅ 适用于单个文件读取,性能好,无需额外依赖。

@Test
public void givenUsingPlainJava_whenConvertingFileToInputStream_thenCorrect() 
  throws IOException {
    File initialFile = new File("src/main/resources/sample.txt");
    InputStream targetStream = new FileInputStream(initialFile);
}

⚠️ 注意:该流需手动关闭(或使用 try-with-resources),否则可能引发资源泄漏。


2.2. DataInputStream

如果你需要从文件中读取二进制数据或基本类型(如 int、double、boolean),可以结合 DataInputStream 使用。

它本身不是文件流,而是装饰器模式的应用,必须包装另一个 InputStream

@Test
public final void givenUsingPlainJava_whenConvertingFileToDataInputStream_thenCorrect() 
  throws IOException {
    final File initialFile = new File("src/test/resources/sample.txt");
    final InputStream targetStream = 
      new DataInputStream(new FileInputStream(initialFile));
}

✅ 适合处理 .dat 等二进制格式文件
❌ 不适用于普通文本读取(建议用 BufferedReader


2.3. SequenceInputStream

当你想把多个文件的内容合并成一个逻辑流时,SequenceInputStream 就派上用场了。

它可以把两个 InputStream 串联起来,按顺序读取。

@Test
public final void givenUsingPlainJava_whenConvertingFileToSequenceInputStream_thenCorrect() 
  throws IOException {
    final File initialFile = new File("src/test/resources/sample.txt");
    final File anotherFile = new File("src/test/resources/anothersample.txt");
    final InputStream targetStream = new FileInputStream(initialFile);
    final InputStream anotherTargetStream = new FileInputStream(anotherFile);
    
    InputStream sequenceTargetStream = 
      new SequenceInputStream(targetStream, anotherTargetStream);
}

✅ 实现文件内容拼接而无需实际合并文件
⚠️ 注意:两个流的关闭行为需特别处理——关闭 SequenceInputStream 会自动关闭内部的两个流

⚠️ 示例中省略了流的关闭逻辑,仅为代码清晰。生产环境务必使用 try-with-resources 或显式关闭。

3. 使用 Guava 转换

Google Guava 提供了更优雅的 IO 操作封装。通过 Files.asByteSource() 可以轻松获得文件的字节源,再打开流。

✅ 代码简洁,API 设计友好
✅ 在使用 Guava 的项目中推荐使用

@Test
public void givenUsingGuava_whenConvertingFileToInputStream_thenCorrect() 
  throws IOException {
    File initialFile = new File("src/main/resources/sample.txt");
    InputStream targetStream = Files.asByteSource(initialFile).openStream();
}

💡 提示:ByteSource 是 Guava 的核心抽象之一,支持缓存、哈希、复制等高级操作,适合复杂场景。

4. 使用 Apache Commons IO 转换

Apache Commons IO 是 Java 开发者的“老朋友”,FileUtils.openInputStream() 方法简洁明了。

✅ 社区广泛使用,稳定性高
✅ 自动处理一些边界情况(如文件不存在抛 IOException

@Test
public void givenUsingCommonsIO_whenConvertingFileToInputStream_thenCorrect() 
  throws IOException {
    File initialFile = new File("src/main/resources/sample.txt");
    InputStream targetStream = FileUtils.openInputStream(initialFile);
}

⚠️ 需引入依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

5. 总结

方式 是否需要依赖 特点
FileInputStream 原生支持,最基础
DataInputStream 用于读取二进制/基本类型
SequenceInputStream 合并多个文件流
✅ Guava Files.asByteSource() API 优雅,功能丰富
✅ Commons IO FileUtils.openInputStream() 简洁稳定,广泛使用

📌 选择建议:

  • 项目无依赖 ➜ 用 FileInputStream
  • 已引入 Guava ➜ 优先用 Files.asByteSource().openStream()
  • 已引入 Commons IO ➜ 直接调 FileUtils.openInputStream()

所有示例代码均可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-io-conversions

这是一个基于 Maven 的项目,导入即可运行,适合本地验证和学习。


原始标题:Java - Convert File to InputStream