8

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,

Sean Nguyen
  • 12,528
  • 22
  • 74
  • 113

6 Answers6

24

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;
}
  • I don't want to do this bc i don't want to have another copy of my byte array. – Sean Nguyen Nov 30 '10 at 16:22
  • 1
    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. – Mike Clark Nov 30 '10 at 16:27
  • Correct. I am only doing this because I "know" the method is passed a ByteArrayInputStream. –  Nov 30 '10 at 16:28
  • I don't want to create another copy of my byte array. Memory concerns in here. – Sean Nguyen Nov 30 '10 at 16:37
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

Vinze
  • 2,549
  • 3
  • 22
  • 23
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.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
1

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

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
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);
Martin Algesten
  • 13,052
  • 4
  • 54
  • 77
-3

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

Darron
  • 21,309
  • 5
  • 49
  • 53