This article shows a few ways to convert an java.io.InputStream to a String.

What are modified line breaks?
Some InputStream to String conversions will modify the original line breaks, which converts the original line breaks to the system property line.separator – which is \r\n on Windows, \n on Linux.

1. ByteArrayOutputStream

Note
This ByteArrayOutputStream solution is the fastest way to convert InputStream to String, less conversion, support input streams with large amounts of data, keep the original line breaks, and it works in all Java versions.

This example opens a website google.com as an InputStream, and we use ByteArrayOutputStream to convert the InputStream to a String and print it out.

ConvertInputStreamToString.java

package com.favtuts.string;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;

public class ConvertInputStreamToString {
    
    public static final int DEFAULT_BUFFER_SIZE = 8192;

    public static void main(String[] args) throws IOException {
        
        URI uri = URI.create("https://www.google.com/");

        try (InputStream inputStream = uri.toURL().openStream()) {
            
            // Convert InputStream -> String
            String result = convertInputStreamToString(inputStream);

            System.out.println(result);
        }
    }

    // Plain Java
    private static String convertInputStreamToString(InputStream is) throws IOException {

        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
        int length;
        while ((length = is.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }

        // Java 1.1
        //return result.toString(StandardCharsets.UTF_8.name());

        return result.toString("UTF-8");

        // Java 10
        //return result.toString(StandardCharsets.UTF_8);

    }
}

2. InputStream#readAllBytes (Java 9)

2.1 In Java 9, we can use the new InputStream#readAllBytes() API to convert the input stream to bytes, later we use the new String() to create a new String object.

// @Java 9 -> inputStream.readAllBytes()
// max bytes Integer.MAX_VALUE, 2147483647, which is 2G
private static String convertInputStreamToString(InputStream inputStream)
        throws IOException {

    return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}

2.2 Review the InputStream source code; it reads all bytes into a byte array, which has a limit of Integer.MAX_VALUE or 2G; Since then, it is not intended for reading input streams with large amounts of data.

InputStream.java

package java.io;

public abstract class InputStream implements Closeable {

  public byte[] readAllBytes() throws IOException {
  		return readNBytes(Integer.MAX_VALUE);
  }

  //...
}

3. InputStreamReader + StringBuilder

The Reader read a char at a time, slow.

// InputStreamReader + StringBuilder
private static String convertInputStreamToString(InputStream inputStream)
        throws IOException {

    final char[] buffer = new char[8192];
    final StringBuilder result = new StringBuilder();

    // InputStream -> Reader
    try (Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
        int charsRead;
        while ((charsRead = reader.read(buffer, 0, buffer.length)) > 0) {
            result.append(buffer, 0, charsRead);
        }
    }

    return result.toString();

}

4. InputStreamReader + BufferedReader (modified line breaks)

The common practice is wrapping the Reader with a BufferedReader.

private static String convertInputStreamToString(InputStream inputStream)
        throws IOException {

    String newLine = System.getProperty("line.separator");
    StringBuilder result = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = reader.readLine()) != null) {
            result
                    .append(line)
                    .append(newLine);
        }
    }
    return result.toString();

}

5. Java 8 BufferedReader#lines (modified line breaks)

Java 8 added a new lines API to the BufferedReader class to convert all lines into a Stream.

private static String convertInputStreamToString4(InputStream inputStream)
        throws IOException {

    String newLine = System.getProperty("line.separator");
    String result;
    try (Stream<String> lines = new BufferedReader(new InputStreamReader(inputStream)).lines()) {
        result = lines.collect(Collectors.joining(newLine));
    }

    return result;

}

6. Apache Commons IO

If you have the commons-io library in the project, try the IOUtils.toString() to convert InputStream to String.

pom.xml

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.11.0</version>
</dependency>
private static String convertInputStreamToString(InputStream inputStream)
  throws IOException {

  return IOUtils.toString(inputStream, StandardCharsets.UTF_8);

}

Review the IOUtils.toString source code, the IOUtils class copy the InputStream into a StringWriter.

package org.apache.commons.io;

public class IOUtils {

  public static String toString(final InputStream input, final Charset charset)
    throws IOException {
    try (final StringBuilderWriter sw = new StringBuilderWriter()) {
        copy(input, sw, charset);
        return sw.toString();
    }
  }

  //...
}

Download Source Code

$ git clone https://github.com/favtuts/java-core-tutorials-examples

$ cd java-string

or

$ cd java-io

References

Leave a Reply

Your email address will not be published. Required fields are marked *