I have a method that takes an InputStream and reads data from it. I would like to use this method with a ByteBuffer also. Is there a way to wrap a ByteBuffer so it can be accessed as a stream?
There seem to be some bugs with the implementation referred to by Thilo, and also copy and pasted on other sites verbatim:
ByteBufferBackedInputStream.read()
returns a sign extended int representation of the byte it reads, which is wrong (value should be in range [-1..255])ByteBufferBackedInputStream.read(byte[], int, int)
does not return -1 when there are no bytes remaining in the buffer, as per the API specByteBufferBackedOutputStream seems relatively sound.
I present a 'fixed' version below. If I find more bugs (or someone points them out) I'll update it here.
Updated: removed synchronized
keywords from read/write methods
public class ByteBufferBackedInputStream extends InputStream {
ByteBuffer buf;
public ByteBufferBackedInputStream(ByteBuffer buf) {
this.buf = buf;
}
public int read() throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
return buf.get() & 0xFF;
}
public int read(byte[] bytes, int off, int len)
throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
len = Math.min(len, buf.remaining());
buf.get(bytes, off, len);
return len;
}
}
public class ByteBufferBackedOutputStream extends OutputStream {
ByteBuffer buf;
public ByteBufferBackedOutputStream(ByteBuffer buf) {
this.buf = buf;
}
public void write(int b) throws IOException {
buf.put((byte) b);
}
public void write(byte[] bytes, int off, int len)
throws IOException {
buf.put(bytes, off, len);
}
}