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()); } } }
得出的运行结果是一样的。