4771

If you have a java.io.InputStream object, how should you process that object and produce a String?


Suppose I have an InputStream that contains text data, and I want to convert it to a String, so for example I can write that to a log file.

What is the easiest way to take the InputStream and convert it to a String?

public String convertStreamToString(InputStream is) {
// ???
}
3
  • Does this answer your question? Scanner is skipping nextLine() after using next() or nextFoo()? Commented Oct 8, 2020 at 14:02
  • 2
    Remember that you need to take the encoding of the input stream in consideration. The system default is not necessarily always the one you wan.t Commented Oct 30, 2020 at 9:52
  • 26
    Most of these answers were written pre-Java 9, but now you can get a byte array from the InputStream using .readAllBytes. So, simply "new String(inputStream.readAllBytes())" works using String's byte[] constructor. Commented May 28, 2021 at 21:19

67 Answers 67

1 2
3
0

In short, think of an InputStream like a conveyor belt of raw materials:

The InputStreamReader is a machine that translates those raw materials into parts (characters).

The BufferedReader is a storage area that batches parts for efficiency. The Stream and Collectors.joining() assemble the parts into the final product (a String).

This is how Java processes streams behind the scenes to give you a String!

Here is an example of how we can do it:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public String convertStreamToString(InputStream is) {
    if (is == null) return "";
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
}
Sign up to request clarification or add additional context in comments.

Comments

-1

Also you can get InputStream from a specified resource path:

public static InputStream getResourceAsStream(String path)
{
    InputStream myiInputStream = ClassName.class.getResourceAsStream(path);
    if (null == myiInputStream)
    {
        mylogger.info("Can't find path = ", path);
    }

    return myiInputStream;
}

To get InputStream from a specific path:

public static URL getResource(String path)
{
    URL myURL = ClassName.class.getResource(path);
    if (null == myURL)
    {
        mylogger.info("Can't find resource path = ", path);
    }
    return myURL;
}

1 Comment

This does not answer the Question.
-1

I had Log4j available, so I was able to use the org.apache.log4j.lf5.util.StreamUtils.getBytes method to get the bytes, which I was able to convert into a string using the String constructor:

String result = new String(StreamUtils.getBytes(inputStream));

1 Comment

-1. Just because something is available doesn't mean it should be used. When you switch the logging provider, you're going to have to replace this. Also, it looks like it is internal and shouldn't really be used outside of log4j.
-3
  InputStream IS=new URL("http://www.petrol.si/api/gas_prices.json").openStream();   

  ByteArrayOutputStream BAOS=new ByteArrayOutputStream();
  IOUtils.copy(IS, BAOS);
  String d= new String(BAOS.toByteArray(),"UTF-8");           

System.out.println(d);

3 Comments

See the commet by ChristofferHammarström in the answer by HarryLime.
There is nothing in the question that would remotely suggest to which charset to convert to or that the solution should be immune to any charset.
An explanation would be in order.
-5

Note: This probably isn't a good idea. This method uses recursion and thus will hit a StackOverflowError very quickly:

public String read (InputStream is) {
    byte next = is.read();
    return next == -1 ? "" : next + read(is); // Recursive part: reads next byte recursively
}

8 Comments

It is not just a bad choice. It will fail with a StackOverflowError if the input stream contains more than a few hundred characters.
@StephenC That constitutes a bad choice in my opinion
I agree. It is a "bad choice" to use a method that doesn't work (except in trivial cases). But not just a "bad choice". Anyhow, I am down voting because this is wrong ... not because it is a "bad choice". And also because you don't explain why this approach should not be used.
For the Java language and implementations, the absence of tail-call optimization is a deliberate design choice; see softwareengineering.stackexchange.com/questions/272061/…. It should be viewed as inherent to Java. Certainly it is common to all extant mainstream Java implementations ... including Android.
@parsecer because instead of running out when the RAM can't handle the memory being used, it dies when the stack can't handle more stack calls, which is a lot smaller of a number on any reasonable system.
|
-5

The easiest way, a one-liner:

public static void main(String... args) throws IOException {
    System.out.println(new String(Files.readAllBytes(Paths.get("csv.txt"))));
}

Comments

-9

Quick and easy:

String result = (String)new ObjectInputStream( inputStream ).readObject();

4 Comments

I get java.io.StreamCorruptedException: invalid stream header
ObjectInputStream is about deserialization, and the stream have to respect the serialization protocol to work, which may not always true in the context of this question.
An explanation would be in order.
Plus oned, good one.
1 2
3

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.