Lorsque je crée un canal de la InputStream avec Channels.newChannel (est) bibliothèque standard Java retourne un ReadableByteChannelImpl, qui est:comportement incohérent ReadableByteChannelImpl Java
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;
}
}
Comme vous pouvez le voir des blocs lors de l'appel de lecture (ByteBuffer dst) pour la première fois, et ne bloque plus jamais. Voir:
if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once
Quelle est la raison derrière un tel comportement étrange?
En outre, quelle est la motivation pour étendre AbstractInterruptibleChannel sans réellement rendre ce canal vraiment interruptible?
Yeap, je l'ai déjà moi-même. La principale raison du blocage pendant le premier appel read() est simplement l'absence de toute méthode fiable pour vérifier si le flux sous-jacent est vide sans le lire réellement. –