Easy Ways to Write a Java InputStream to an OutputStream – 将Java输入流写入输出流的简单方法

最后修改: 2020年 6月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’re going to learn how to write a Java InputStream to a Java OutputStream. We’ll first use core functionality from Java 8 and Java 9. Then, we’ll look at a couple of external libraries — Guava and the Apache Commons IO library.

在这个快速教程中,我们将学习如何将一个Java InputStream写到一个Java OutputStream。我们将首先使用Java 8和Java 9的核心功能。 然后,我们将看看几个外部库 – GuavaApache Commons IO库

The utility methods provided by Java 9, Guava, and Apache Commons IO do not flush or close the streams. So, we’ll need to manage these resources by using try-with-resources or a finally block.

Java 9、Guava和Apache Commons IO所提供的实用方法并没有冲刷或关闭流。因此,我们需要通过使用try-with-resourcesfinally块来管理这些资源。

2. Using Java 8

2.使用Java 8

First, we’ll begin by creating a simple method using vanilla Java to copy the content from the InputStream to the OutputStream:

首先,我们将使用vanilla Java创建一个简单的方法,将内容从InputStream复制到OutputStream

void copy(InputStream source, OutputStream target) throws IOException {
    byte[] buf = new byte[8192];
    int length;
    while ((length = source.read(buf)) != -1) {
        target.write(buf, 0, length);
    }
}

This code is pretty straightforward — we’re simply reading in some bytes and then writing them out.

这段代码非常简单–我们只是读入一些字节,然后把它们写出来。

3. Using Java 9

3.使用Java 9

Java 9 provides a utility method, InputStream.transferTo(), for this task.

Java 9为这项任务提供了一个实用方法,InputStream.transferTo()

Let’s look at how we would use the transferTo() method:

让我们看看我们将如何使用transferTo()方法。

@Test
public void givenUsingJavaNine_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        inputStream.transferTo(targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

Note that when working with file streams, it’s more efficient to use Files.copy() than the transferTo() method.

请注意,在处理文件流时,使用Files.copy()比使用transferTo()方法更有效率。

4. Using Guava

4.使用番石榴

Next, let’s look at how we would use Guava’s utility method ByteStreams.copy().

接下来,让我们看看我们如何使用Guava的实用方法ByteStreams.copy()

We’ll need to include the guava dependency in our pom.xml:

我们需要在pom.xml中包含guava依赖项

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

Let’s create a simple test case to show how we could use ByteStreams to copy data:

让我们创建一个简单的测试案例来展示我们如何使用ByteStreams来复制数据。

@Test
public void givenUsingGuava_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        ByteStreams.copy(inputStream, targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

5. Using Commons IO

5.使用Commons IO

Finally, let’s look at how we would use the Commons IO IOUtils.copy() method for this task.

最后,让我们看看我们如何使用Commons IO IOUtils.copy()方法来完成这项任务。

Of course, we’ll need to add the commons-io dependency to the pom.xml:

当然,我们需要将commons-io依赖性添加到pom.xml中。

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

Let’s create a simple test case using IOUtils to copy data from the input stream to the output stream:

让我们使用IOUtils创建一个简单的测试案例,将数据从输入流复制到输出流。

@Test
public void givenUsingCommonsIO_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        IOUtils.copy(inputStream, targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

Note: Commons IO provides additional methods for working with InputStreams and OutputStreams. IOUtils.copyLarge() should be used whenever it is necessary to copy 2 GB or more of data.

注意:Commons IO为处理InputStreams和OutputStreams提供额外的方法。IOUtils.copyLarge()应该在需要复制2GB或更多数据的时候使用。

6. Conclusion

6.结语

In this article, we explored simple ways to copy data from an InputStream to an OutputStream.

在这篇文章中,我们探讨了将数据从InputStream复制到OutputStream的简单方法。

The implementation of these examples is available over on GitHub.

这些例子的实现可以在GitHub上获得