9

I want to get the internal byte array from ByteArrayInputStream. I don't want to extends that class or write it into another byte array. Is there a utility class that help me do that?

Thanks,

6 Answers 6

25

You can not get access to the same byte array, but you can easily copy the contents of the stream:

public byte[] read(ByteArrayInputStream bais) {
     byte[] array = new byte[bais.available()];
     bais.read(array);

     return array;
}
Sign up to request clarification or add additional context in comments.

4 Comments

I don't want to do this bc i don't want to have another copy of my byte array.
While this code should work in practice because of our internal knowledge of the operation of java.io.ByteArrayInputStream, in theory it doesn't abide by the contract of InputStream, which -- to be correct -- needs you to check the return value of the read method to detect a partial read.
Correct. I am only doing this because I "know" the method is passed a ByteArrayInputStream.
I don't want to create another copy of my byte array. Memory concerns in here.
4

With the library Apache COmmons IO (http://commons.apache.org/io/) you can use the IOUtils.toByteArray(java.io.InputStream input)

Edit : ok, I didn't understood the question... no copy... Maybe something like :

byte[] buf = new byte[n];
ByteArrayInputStream input = new ByteArrayInputStream(buf);

will allow you to keep a reference to the buffer used by the input stream

1 Comment

It is IOUtils (capital U, I believe)
3

Extend ByteArrayInputStream, then you have access to the protected fields. It's the way to do it. Constructors are provided to take the byte array from an argument.

However, you may find the decorator pattern more helpful.

Comments

1

No. Extending the class is the only way (well, that and using reflection to bypass the field visibility, which absolutely NOT recommended).

4 Comments

why you are not recommending reflection?
@Sean: because it's slow and error-prone (and won't work at all if the code runs in a sandbox).
Can you explain more about "it's slow"? Running in a sandbox you mean with security settings?
@Sean: accessing fields throgh reflection is at least an order of magnitude slower than doing it directly. And yes, you need to use setAccessible() to access a protected field through reflection, and that can be prohibited by a SecurityManager.
0

The internal field is protected, so extending would be easy. If you really don't want to, reflection may be another way. This is not a great solution since it relies on internal workings of ByteArrayInputStream (such as knowing the field is called buf). You have been warned.

ByteArrayInputStream bis = ...
Field f = ByteArrayInputStream.class.getDeclaredField("buf");
f.setAccessible(true);
byte[] buf = (byte[])f.get(bis);

Comments

-3

No, access to the internal array is not provided except through the toByteArray() method, which makes a copy.

3 Comments

Where did you find toByteArray in ByteArrayInputStream?
toByteArray() only exists in ByteArrayOutputStream
He confused ByteArrayOutputStream with ByteArrayInputStream.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.