Java NIO。为什么flip()方法会破坏我的程序?

时间:2012-07-20 14:57:51

标签: java nio bytebuffer socketchannel

下面的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()

接下来,我将缓冲区“请求”,此字符串的长度 7 ,但方法write()返回 1017

什么信息方法写入频道?

我不确定,该方法写了字符串“请求”

好的,我再次修改了我的代码:

    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

并且代码崩溃了......

为什么?我的错误在哪里?

感谢。

2 个答案:

答案 0 :(得分:6)

在从缓冲区读取数据之前,需要将flip方法称为flip()方法,将缓冲区的limit重置为当前位置,并将缓冲区的position重置为0.

因此,如果您在ByteBuffer中有7个字节的数据,那么您的位置(从0开始)将是7. flip(),它会使limit = 7,{{ 1}}。现在,可以进行阅读。

以下是有关如何最好地使用position = 0的示例:

flip()

答案 1 :(得分:3)

尽管其名称(选择不当),但flip()不对称。您必须在从缓冲区(写入或获取)获取的任何操作之前调用它,然后调用compact()clear()以将缓冲区恢复到准备好读取或放入的状态。