3

My application gets a large number of large InputStreams, and needs to hand them off to a driver expecting ByteBuffers. Java InputStream to ByteBuffer recommends converting them to byte arrays first; however, that is expensive, and indeed ruins the whole point of using NIO. I'm looking for a way that a driver expecting a ByteBuffer can read from the InputStream as it needs to.

In the case I'm dealing with, consuming the entire InputStream at once and turning it into an array is too expensive and wasteful.

Community
  • 1
  • 1
SRobertJames
  • 8,210
  • 14
  • 60
  • 107

2 Answers2

3

You can hardly ever do this without reading the whole InputStream first.

ByteBuffer API is random access, while InputStream is strictly sequential.

Furthermore, you cannot make your own subclass of ByteBuffer since its constructor is package private and java.nio package is restricted. That is, you cannot wrap an InputStream into ByteBuffer; you have to use either ByteBuffer.wrap(byte[]) or ByteBuffer.allocateDirect().

apangin
  • 92,924
  • 10
  • 193
  • 247
0

I dont think this is possible. No matter if you are using ByteBuffer or just reading from the InputStream eventually you are using a byte array that has been created by someone. Now when you pass the byte array to the Buffer the Buffer is not initializing a new byte array it is reusing what you are actually passing. This fragment is taken straight from the Java 8 source code see for yourself:

ByteBuffer(int mark, int pos, int lim, int cap,   // package-private
274                  byte[] hb, int offset)
275     {
276         super(mark, pos, lim, cap);
277         this.hb = hb;
278         this.offset = offset;
279     }

As you see in the above fragment the ByteBuffer is using the byte array straight it is not coping it over again.So there is 0 penalty for the fact that you have read a byte array. You should not be afraid of applying the post you have linked in practice. There will be no performance penalty.

Alexander Petrov
  • 9,204
  • 31
  • 70