Channels.newChannel(is) を使用して InputStream からチャネルを作成すると、Java 標準ライブラリは次のような ReadableByteChannelImpl を返します。
private static class ReadableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements ReadableByteChannel
{
InputStream in;
private static final int TRANSFER_SIZE = 8192;
private byte buf[] = new byte[0];
private boolean open = true;
private Object readLock = new Object();
ReadableByteChannelImpl(InputStream in) {
this.in = in;
}
public int read(ByteBuffer dst) throws IOException {
int len = dst.remaining();
int totalRead = 0;
int bytesRead = 0;
synchronized (readLock) {
while (totalRead < len) {
int bytesToRead = Math.min((len - totalRead),
TRANSFER_SIZE);
if (buf.length < bytesToRead)
buf = new byte[bytesToRead];
if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once
try {
begin();
bytesRead = in.read(buf, 0, bytesToRead);
} finally {
end(bytesRead > 0);
}
if (bytesRead < 0)
break;
else
totalRead += bytesRead;
dst.put(buf, 0, bytesRead);
}
if ((bytesRead < 0) && (totalRead == 0))
return -1;
return totalRead;
}
}
protected void implCloseChannel() throws IOException {
in.close();
open = false;
}
}
ご覧のとおり、 read(ByteBuffer dst) を初めて呼び出すとブロックされ、再度ブロックされることはありません。見る:
if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once
そのような奇妙な行動の背後にある理由は何ですか?
また、実際にこのチャネルを本当に中断可能にせずに AbstractInterruptibleChannel を拡張する動機は何ですか?