i have a question about using reusing ByteBuffer
s from java.nio multiple times to produce InputStreams
. i've found a nice converter in jackson called ByteBufferBackedInputStream
. my problem however is that i want to potentially have multiple InputStream
s open at the same time, backed by the same underlying ByteBuffer
. consider,
@Test
void testStuff() throws Exception {
ByteBuffer bb = ByteBuffer.allocateDirect(42);
for (int i = 0; i < 42; i++) {
bb.put((byte) i);
}
bb.flip();
InputStream foo = new ByteBufferBackedInputStream(bb);
InputStream bar = new ByteBufferBackedInputStream(bb);
byte[] eightyFourBytes = new byte[84];
int readFromFoo = foo.read(eightyFourBytes);
int readFromBar = bar.read(eightyFourBytes);
assertThat(readFromFoo).isEqualTo(42);
assertThat(readFromBar).isEqualTo(42); // oops! reading mutated the underlying ByteBuffer's position
}
i'm scratching my head to work out a solution to this. i need this because,
ByteBuffers
for better file io performance (that using it is fairly drop-in for file io is important as well), and to reduce GC pressure,InputStream
, and is inflexible,i guess my question is, is there an alternative to ByteBuffer
, or a better way of using it than i am? obviously i could just manually reset the buffer between usages, but doing that seems brittle and in my mind the ideal solution can produce InputStream
s that i can hand off without thinking about it.
The simple approach is to hand out a read only copy:
InputStream foo = new ByteBufferBackedInputStream(bb.asReadOnlyBuffer());
The buffer will be shared, but each copy will get its own position, limit and mark. Note that changes to the data in the buffer will be seen by all clients, so you need to be really sure that nobody is using your buffer before you return it to the pool again! Depending on your use case, that may be easy or very hard. If it is hard, pooling might not be such a good idea.