実際の実装がないように思われるので、速度をテストするための初期実装をすぐに書きました。
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;
}
}
36メガのファイルをコピーしてテストしています。もちろん、多くはファイルのやり取りに依存しますが、一般的には、bytearrayinputstream よりも書き込みの方がわずかに速い (5 ~ 20% の増加)。
すぐにまとめたので、バグを見つけたら教えてください。
編集:
読み込まれた配列がデフォルトで gc 用に解放される機能を追加