Easy Ways to Write a Java InputStream to an OutputStream

1. Overview

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.

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.

2. Using Java 8

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

void copy(InputStream source, OutputStream target) throws IOException {
    byte[] buf = new byte[8192];
    int length;
    while ((length = source.read(buf)) > 0) {
        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

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

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

@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.

4. Using Guava

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

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

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

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

@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

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

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

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

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

@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.

6. Conclusion

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

The implementation of these examples is available over on GitHub.

Related posts:

New in Spring Security OAuth2 – Verify Claims
Java Program to Check if a Given Set of Three Points Lie on a Single Line or Not
Java Program to Implement Self organizing List
The Thread.join() Method in Java
Java Program to Implement Direct Addressing Tables
Comparing Dates in Java
OAuth2 for a Spring REST API – Handle the Refresh Token in AngularJS
Getting Started with Custom Deserialization in Jackson
A Guide to Queries in Spring Data MongoDB
Bootstrap a Web Application with Spring 5
Java Program to Implement Hash Tables Chaining with List Heads
Simplify the DAO with Spring and Java Generics
Using the Not Operator in If Conditions in Java
Spring 5 and Servlet 4 – The PushBuilder
Spring Boot Configuration with Jasypt
Concatenating Strings In Java
Java Program to Find the Shortest Path from Source Vertex to All Other Vertices in Linear Time
SOAP Web service: Authentication trong JAX-WS
Java Program to Implement ArrayDeque API
Debugging Reactive Streams in Java
Converting Java Date to OffsetDateTime
Guide to CopyOnWriteArrayList
Java Program to Implement Hash Trie
Lập trình đa luồng với CompletableFuture trong Java 8
Java Program to Convert a Decimal Number to Binary Number using Stacks
RegEx for matching Date Pattern in Java
Java Program to Implement Ternary Search Tree
Java Program to Implement Sparse Array
Biến trong java
Làm thế nào tạo instance của một class mà không gọi từ khóa new?
Tạo ứng dụng Java RESTful Client với thư viện Retrofit
Spring Security 5 – OAuth2 Login