たとえば、100500 バイトを配列に読み込みたい:
byte[] array = new byte[100500];
int offset = 0;
ByteBuffer buf = ByteBuffer.directBuffer(4096);
channel.read(buffer, null, new LambdaAdapter((count, exception, attachment) -> {
buf.get(array, offset, count);
offset += count; //will not work, offset must be final
if (offset < 100500) {
channel.read(buffer, null, /*what here? must be lambda we are currently in but we can't use it!*/)
}
//here we have our 100500 bytes inside array
});
ここでの LambdaAdapter は、CompletionHandler を 3 つの引数を持つ関数型インターフェイスに変換する単純なラッパーです。
ともかく。オフセットは「アタッチメント」パラメーターに入れることができ、ラムダは事前に宣言してフィールドとして再利用できます。ただし、結果として得られるコードは常に醜い醜い醜いものです。
このような単純なタスクでも、許容できるソリューションを作成できませんでした。読み取りが書き込みとインターリーブされ、複雑なロジックでラップされる複雑なプロトコルの場合はどうなるでしょうか。
非同期APIを処理する適切な方法を知っている人はいますか? ここで Scala が世界を救うことができると思われる場合は、気軽に使用してください。