0

以下のJavaコード:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class Test {
    public static void main(String args[]) throws IOException {

        SocketChannel c = SocketChannel.open();
        c.connect(new InetSocketAddress("google.com", 80));

        ByteBuffer b = ByteBuffer.allocate(1024);
        b.put("Request".getBytes());

        System.out.println("Write: " + c.write(b));

        int i;
        while ((i = c.read(b)) != -1) {

            System.out.println("Read: " + i);
            b.clear();

        }
    }
}

実結果:

書き込み:1017読み取り:0読み取り:1024読み取り:44

初めて、メソッドread()は0バイトを読み取りました。かっこいいじゃない。

コードを変更しました:

    b.put("Request".getBytes());

    System.out.println("Write: " + c.write(b));

    b.flip(); //I added this line
    int i;
    while ((i = c.read(b)) != -1) {

        System.out.println("Read: " + i);
        b.clear();

    }

実績:

書き込み:1017読み取り:1024読み取り:44

すでに良く見えます。これをありがとうflip()

次に、バッファ文字列"Request"に入れます。この文字列の長さは7ですが、メソッドは1017write()を返しました。

どのような情報方法がチャネルに書き込まれましたか?

そのメソッドが文字列「Request」を書き込んだかどうかはわかりません。

わかりました。コードをもう一度変更しました。

    b.put("Request".getBytes());

    b.flip(); // I added this line
    System.out.println("Write: " + c.write(b));

    b.flip();
    int i;
    while ((i = c.read(b)) != -1) {

        System.out.println("Read: " + i);
        b.clear();

    }

実績:

書き込み:7

とコードがクラッシュしました...

なぜですか?私の間違いはどこにありますか?

ありがとう。

4

2 に答える 2

6

バッファからデータを読み取る前にflipメソッドを呼び出す必要があります。この方法では、バッファを現在の位置にリセットし、バッファを0にリセットします。flip()limitposition

したがって、に7バイトのデータがあるByteBuffer場合、位置(0から開始)は7になりflip()ます。これで、読み取りが発生する可能性があります。limit = 7position = 0

最適な使用方法の例を次に示しますflip()

public static final void nioCopy(ReadableByteChannel input, WritableByteChannel output) throws IOException {
    ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while (input.read(buffer) != -1) {
        //Flip buffer
        buffer.flip();
        //Write to destination
        output.write(buffer);
        //Compact
        buffer.compact();
    }

    //In case we have remainder
    buffer.flip();
    while (buffer.hasRemaining()) {
        //Write to output
        output.write(buffer);
    }
}
于 2012-07-20T15:17:32.723 に答える
3

その(不十分に選択された)名前にもかかわらず、flip()対称的ではありません。バッファから取得する操作(書き込みまたは取得)の前にこれを呼び出し、いずれかcompact()またはclear()後で呼び出して、バッファを読み取りまたは書き込みの準備ができた状態に戻す必要があります。

于 2012-07-20T19:43:42.267 に答える