38

I read this post but I am not following. I have seen this but have not seen a proper example of converting a ByteArrayInputStream to String using a ByteArrayOutputStream.

To retrieve the contents of a ByteArrayInputStream as a String, is using a ByteArrayOutputstream recommended or is there a more preferable way?

I was considering this example and extend ByteArrayInputStream and utilize a Decorator to increase functionality at run time. Any interest in this being a better solution to employing a ByteArrayOutputStream?

Community
  • 1
  • 1
Mushy
  • 2,535
  • 10
  • 33
  • 54
  • 1
    You probably want an `InputStreamReader`, as described in the second link that you gave. A `ByteArrayOutputStream` won't convert the bytes to characters. – Dawood ibn Kareem Jun 05 '14 at 11:45
  • Do you really have a ByteArrayInputStream (which implies you have a byte[]) or do you just have an InputStream? – Brett Okken Jun 05 '14 at 11:46
  • @BrettOkken I really have a ByteArrayInputStream whose constructor is passed an array of bytes (varying size) – Mushy Jun 05 '14 at 12:04
  • @DavidWallace There was a reply to the post in the second link using an InputstreamReader: `The problem with this is that it reads only up to and including the first line separator. It assumes that the string you're looking for does not contain any line separators. Often that's true, but if not, this won't really work.` Why I am not proceeding with that example. – Mushy Jun 05 '14 at 12:08
  • But you can just keep reading from it until it's empty. – Dawood ibn Kareem Jun 05 '14 at 23:57

5 Answers5

55

A ByteArrayOutputStream can read from any InputStream and at the end yield a byte[].

However with a ByteArrayInputStream it is simpler:

int n = in.available();
byte[] bytes = new byte[n];
in.read(bytes, 0, n);
String s = new String(bytes, StandardCharsets.UTF_8); // Or any encoding.

For a ByteArrayInputStream available() yields the total number of bytes.


Addendum 2021-11-16

Since java 9 you can use the shorter readAllBytes.

byte[] bytes = in.readAllBytes();

Answer to comment: using ByteArrayOutputStream

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
for (;;) {
    int nread = in.read(buf, 0, buf.length);
    if (nread <= 0) {
        break;
    }
    baos.write(buf, 0, nread);
}
in.close();
baos.close();
byte[] bytes = baos.toByteArray();

Here in may be any InputStream.


Since java 10 there also is a ByteArrayOutputStream#toString(Charset).

String s = baos.toString(StandardCharsets.UTF_8);
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • 1
    How would a ByteArrayOutputStream read from a ByteArrayInputStream? – Mushy Jun 05 '14 at 12:37
  • 2
    I have extended the answer. In principle one loops reading from the `InputStream` and writing to the `ByteArrayOutputStream`. Out of tradition the I/O buffer has a ritual size being a power of 2. – Joop Eggen Jun 05 '14 at 14:33
  • Agree with power of 2 size; I like that and thank you. – Mushy Jun 05 '14 at 14:59
  • From the javadoc of the [InputStream.available()](https://docs.oracle.com/javase/9/docs/api/java/io/InputStream.html#available--) function: _It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream._ – nucatus May 23 '21 at 05:58
  • @nucatus true, I did not state that `in` is that `ByteArrayInputStream`. For [ByteArrayInputStream#available()](https://docs.oracle.com/javase/10/docs/api/java/io/ByteArrayInputStream.html#available()) one may. – Joop Eggen May 23 '21 at 08:33
29

Why nobody mentioned org.apache.commons.io.IOUtils?

import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

String result = IOUtils.toString(in, StandardCharsets.UTF_8);

Just one line of code.

dokaspar
  • 8,186
  • 14
  • 70
  • 98
Cherry
  • 31,309
  • 66
  • 224
  • 364
  • 3
    I added the two required `import` statements so that not everyone has to search for them. Sorry... it's not just one line of code anymore ;) – dokaspar Sep 08 '17 at 11:12
  • 1
    Sorry but I think this answer is not correct. Because if your input is ByteArrayInputStream you will get compile error. The correct input for this function is InputStream – vicangel Aug 17 '20 at 10:24
10

Java 9+ solution:

new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
2

Use Scanner and pass to it's constructor the ByteArrayInputStream then read the data from your Scanner , check this example :

ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(new byte[] { 65, 80 });
Scanner scanner = new Scanner(arrayInputStream);
scanner.useDelimiter("\\Z");//To read all scanner content in one String
String data = "";
if (scanner.hasNext())
    data = scanner.next();
System.out.println(data);
Mifmif
  • 3,132
  • 18
  • 23
1

Use Base64 encoding

Assuming you got your ByteArrayOutputStream :

ByteArrayOutputStream baos =...
String s = new String(Base64.Encoder.encode(baos.toByteArray()));

See http://docs.oracle.com/javase/8/docs/api/java/util/Base64.Encoder.html

Bowser Jr.
  • 31
  • 3