Since there seems to be no real implementation, I quickly wrote an initial implementation to test the speed:
public class Buffer { private int size; private int writeIndex, writeOffset, readIndex, readOffset; private List<byte[]> backingArrays = new ArrayList<byte[]>(); public Buffer() { this(10240); } public Buffer(int size) { this.size = size; } public int read(byte [] bytes) { return read(bytes, 0, bytes.length); } public int read(byte [] bytes, int offset, int length) { int read = 0; while(length > 0) { byte [] input = getInput(); // no more data if (input == null) { if (read == 0) return -1; else return read; } int readLength = Math.min(length, (readIndex == writeIndex ? writeOffset : size) - readOffset); System.arraycopy(input, readOffset, bytes, offset, readLength); length -= readLength; offset += readLength; readOffset += readLength; read += readLength; } return read; } public void write(byte [] bytes) { write(bytes, 0, bytes.length); } public void write(byte [] bytes, int offset, int length) { while (length > 0) { byte [] output = getOutput(); int writeLength = Math.min(length, output.length - writeOffset); System.arraycopy(bytes, offset, output, writeOffset, writeLength); length -= writeLength; offset += writeLength; writeOffset += writeLength; } } private byte[] getOutput() { // if we have filled an array, move to the next one if (writeOffset >= size) { writeIndex++; writeOffset = 0; } // create it if it doesn't exist yet if (backingArrays.size() <= writeIndex) backingArrays.add(new byte[size]); return backingArrays.get(writeIndex); } private byte [] getInput() { // nothing written yet if (backingArrays.size() == 0) return null; if (readOffset >= size) { readIndex++; readOffset = 0; } // can not read past where it is written if (readIndex > writeIndex || (readIndex == writeIndex && readOffset >= writeOffset)) return null; else return backingArrays.get(readIndex); } public long size() { return (long) size * (long) writeIndex + writeOffset; } }
I am testing it by copying a 36 megabyte file. Much depends on the interaction of the files, but, as a rule, it is 40% faster to read a little faster than writing than bytearrayinputstream (it hangs by about 5-20%)
I put it together quickly, so if you catch any errors let me know.
EDIT
Added function, by default released arrays released for gc
source share