购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3.10 对缓冲区进行反转

final Buffer flip()方法的作用:反转此缓冲区。首先将限制设置为当前位置,然后将位置设置为0。如果已定义了标记,则丢弃该标记。

flip()方法的通俗解释是“缩小limit的范围,类似于String.subString(0,endIndex)方法”。

flip()方法的内部源代码如下:

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

当向缓冲区中存储数据,然后再从缓冲区中读取这些数据时,就是使用flip()方法的最佳时机,示例代码如下:

A—buf.allocate(10);
B—buf.put(8);
C—首先向buf写入数据,此步骤是重点操作;
D—buf.flip();
E—然后从buf读出数据,此步骤是重点操作。

当执行A处代码时,缓冲区出现10个空的位置,索引形式如下:

0  1  2  3  4  5  6  7  8  9

当执行B处代码时,position为0的位置存入数字8,然后position自动变成1,因为put()方法会将position进行自增,这时缓冲区中的数据如下:

0  1  2  3  4  5  6  7  8  9
8

当执行C处代码时,假设要写入的数据数组为{11,22,33,44,55},将这5个数字在position是1的位置依次存入buf中,完成后的缓冲区中的数据如下:

0  1   2   3   4   5   6   7   8   9
8  11  22  33  44  55

这时position的值是6,下一步要将缓冲区中的数据读取出来时,有效的数据应该是:

8 11 22 33 44 55

因为位置6~7~8~9中存储的值是无效的,所以调用D处代码flip()后将position的值6作为limit的值,而position被重新赋值为0,有效数据的范围为:

0  1   2   3   4   5
8  11  22  33  44  55

最后执行E处代码,将这些有效的数据读取出来。

final Buffer flip()方法常用在向缓冲区中写入一些数据后,下一步读取缓冲区中的数据之前,以改变limit与position的值。

方法flip会改变position和limit的值,示例代码如下:

public class Test11 {

public static void main(String[] args) {
    byte[] byteArray = new byte[] { 1, 2, 3 };

    ByteBuffer bytebuffer = ByteBuffer.wrap(byteArray);

    bytebuffer.position(2);
    bytebuffer.mark();

    bytebuffer.flip();

    System.out.println("bytebuffer.position=" + bytebuffer.position());
    System.out.println();

    System.out.println("bytebuffer.limit=" + bytebuffer.limit());
    System.out.println();

    try {
        bytebuffer.reset();
    } catch (java.nio.InvalidMarkException e) {
        System.out.println("bytebuffer mark丢失");
    }
}
}

程序运行结果如下:

bytebuffer.position=0

bytebuffer.limit=2

bytebuffer mark丢失

final Buffer flip()方法常用在向缓冲区中写入一些数据后,下一步读取缓冲区中的数据之前调用,以改变limit与position的值,示例代码如下:

public class Test11_1 {

public static void main(String[] args) {
    CharBuffer charBuffer = CharBuffer.allocate(20);
    System.out.println("A position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 一共写入14个字
    charBuffer.put("我是中国人我在中华人民共和国");
    System.out.println("B position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    charBuffer.position(0);// 位置position还原成0
    System.out.println("C position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 下面for语句的打印效果是“国”字后面有6个空格,这6个空格是无效的数据
    // 应该只打印前14个字符,后6个字符不再读取
    for (int i = 0; i < charBuffer.limit(); i++) {
        System.out.print(charBuffer.get());
    }
    System.out.println();
    // 上面的代码是错误读取数据的代码

    // 下面的代码是正确读取数据的代码
    System.out.println("D position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 还原缓冲区的状态
    charBuffer.clear();
    System.out.println("E position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 继续写入
    charBuffer.put("我是美国人");
    System.out.println("F position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 设置for循环结束的位置,也就是新的limit值
    charBuffer.limit(charBuffer.position());
    charBuffer.position(0);
    System.out.println("G position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    for (int i = 0; i < charBuffer.limit(); i++) {
        System.out.print(charBuffer.get());
    }
}
}

程序运行结果如下:

A position=0 limit=20
B position=14 limit=20
C position=0 limit=20
我是中国人我在中华人民共和国空格空格空格空格空格空格
D position=20 limit=20
E position=0 limit=20
F position=5 limit=20
G position=0 limit=5
我是美国人

上面的程序在读取数据时都要执行以下代码:

charBuffer.limit(charBuffer.position());
charBuffer.position(0);

这样会显得比较烦琐,可以使用flip()方法,示例代码如下:

public class Test11_2 {
public static void main(String[] args) {
    CharBuffer charBuffer = CharBuffer.allocate(20);
    System.out.println("A position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 一共写入14个字
    charBuffer.put("我是中国人我在中华人民共和国");
    System.out.println("B position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    charBuffer.position(0);// 位置position还原成0
    System.out.println("C position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 下面for语句的打印效果是“国”字后面有6个空格,这6个空格是无效的数据
    // 应该只打印前14个字符,后6个字符不再读取
    for (int i = 0; i < charBuffer.limit(); i++) {
        System.out.print(charBuffer.get());
    }
    System.out.println();
    // 上面的代码是错误读取数据的代码

    // 下面的代码是正确读取数据的代码
    System.out.println("D position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 还原缓冲区的状态
    charBuffer.clear();
    System.out.println("E position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 继续写入
    charBuffer.put("我是美国人");
    System.out.println("F position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    // 使用flip()方法
    charBuffer.flip();
    System.out.println("G position=" + charBuffer.position() + " limit=" +
    charBuffer.limit());
    for (int i = 0; i < charBuffer.limit(); i++) {
        System.out.print(charBuffer.get());
    }
}
}

得出的运行结果是一样的。 ucFMaeiOBXpNn4MfhD/mKg9bYgEbDkj0UBUtndL2fiPhATHxasZOdYwUIchZZDOI

点击中间区域
呼出菜单
上一章
目录
下一章
×