在Java NIO编程中,对缓冲区操作常常需要使用  java.nio.Buffer中的 flip()方法。

  Buffer 中的 flip() 方法涉及到 Buffer 中的capacity、position、limit三个概念。

  capacity:在读/写模式下都是固定的,就是我们分配的缓冲大小(容量)。

position:类似于读/写指针,表示当前读(写)到什么位置。

limit:在写模式下表示最多能写入多少数据,此时和capacity相同。在读模式下表示最多能读多少数据,此时和缓存中的实际

数据大小相同。

flip():Buffer有两种模式,写模式和读模式。在写模式下调用flip()之后,Buffer从写模式变成读模式。

那么limit就设置成了position当前的值(即当前写了多少数据),postion会被置为0,以表示读操作从缓存的头开始读,mark置为-1。

也就是说调用flip()之后,读/写指针position指到缓冲区头部,并且设置了最多只能读出之前写入的数据长度(而不是整个缓存的容量大小)。

例子分析,这三个属性的作用

1.分配内存大小为10的缓存区。索引10的空间是我虚设出来,实际不存在,为了能明显表示capacity。IntBuffer的容量为10,所以capacity为10,在这里指向索引为10的空间。Buffer初始化的时候,limit和capacity指向同一索引。position指向0。

2.往Buffer里加一个数据。position位置移动,capacity不变,limit不变。

3.Buffer读完之后,往bufer里写了5个数据,position指向索引为5的第6个数据,capacity不变,limit不变。

4.执行flip()。这时候对照着,之前flip源码去看。把position的值赋给limit,所以limit=5,然后position=0。capacity不变。结果就是: 

5.Buffer开始往外写数据。每写一个,position就下移一个位置,一直移到limit的位置,结束。

上图的顺序就是代码中的IntBuffer从初始化,到读数据,再写数据三个状态下,capacity,position,limit三个属性的变化和关系。 

大家可以发现: 

1. 0 <= position <= limit <= capacity 

2. capacity始终不变

图中很好的阐述了,Buffer读写切换的过程。即flip()的反转原理。接下来我们从代码中检测上面的分析过程。想一下下面代码打印的内容,然后执行一编代码看看对不对。

flip()源码:

    public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
public class NioTest {
public static void main(String[] args) {
// 分配内存大小为10的缓存区
IntBuffer buffer = IntBuffer.allocate(10); System.out.println("capacity:" + buffer.capacity()); for (int i = 0; i < 5; ++i) {
int randomNumber = new SecureRandom().nextInt(20);
buffer.put(randomNumber);
} System.out.println("before flip limit:" + buffer.limit()); buffer.flip(); System.out.println("after flip limit:" + buffer.limit()); System.out.println("enter while loop"); while (buffer.hasRemaining()) {
System.out.println("position:" + buffer.position());
System.out.println("limit:" + buffer.limit());
System.out.println("capacity:" + buffer.capacity());
System.out.println("元素:" + buffer.get());
}
}
}

实例代码(借用Java编程思想P552的代码):


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; /**
* 获取通道
*
*
*/
public class GetChannel {
private static final int SIZE = 1024; public static void main(String[] args) throws Exception {
// 获取通道,该通道允许写操作
FileChannel fc = new FileOutputStream("data.txt").getChannel();
// 将字节数组包装到缓冲区中
fc.write(ByteBuffer.wrap("Some text".getBytes()));
// 关闭通道
fc.close(); // 随机读写文件流创建的管道
fc = new RandomAccessFile("data.txt", "rw").getChannel();
// fc.position()计算从文件的开始到当前位置之间的字节数
System.out.println("此通道的文件位置:" + fc.position());
// 设置此通道的文件位置,fc.size()此通道的文件的当前大小,该条语句执行后,通道位置处于文件的末尾
fc.position(fc.size());
// 在文件末尾写入字节
fc.write(ByteBuffer.wrap("Some more".getBytes()));
fc.close(); // 用通道读取文件
fc = new FileInputStream("data.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
// 将文件内容读到指定的缓冲区中
fc.read(buffer);
buffer.flip();// 此行语句一定要有
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
fc.close();
}
}

  注意:buffer.flip();一定得有,如果没有,就是从文件最后开始读取的,当然读出来的都是byte=0时候的字符。通过buffer.flip();这个语句,就能把buffer的当前位置更改为buffer缓冲区的第一个位置。

java.nio.Buffer 中的 flip()方法的更多相关文章

  1. Java NIO Buffer中各种状态属性的含义

    关于NIO Buffer中的3个重要状态属性的含义: postion, limit与capacity. public class NioTest { public static void main(S ...

  2. java.nio.ByteBuffer中的flip()、rewind()、compact()等方法的使用和区别

    java.nio.ByteBuffer 1. ByteBuffer中的参数position.limit.capacity.mark含义: position:表示当前指针的位置(下一个要操作的数据元素的 ...

  3. java.nio.ByteBuffer中flip,rewind,clear方法的区别

    对缓冲区的读写操作首先要知道缓冲区的下限.上限和当前位置.下面这些变量的值对Buffer类中的某些操作有着至关重要的作用: limit:所有对Buffer读写操作都会以limit变量的值作为上限. p ...

  4. java.nio.ByteBuffer中flip、rewind、clear方法的区别

    对缓冲区的读写操作首先要知道缓冲区的下限.上限和当前位置.下面这些变量的值对Buffer类中的某些操作有着至关重要的作用: limit:所有对Buffer读写操作都会以limit变量的值作为上限. p ...

  5. java NIO Buffer 详解(1)

    1.java.io  最为核心的概念是流(stream),面向流的编程,要么输入流要么输出流,二者不可兼具: 2.java.nio 中拥有3个核心概念: Selector Channel, Buffe ...

  6. Java NIO —— Buffer(缓冲区)

    Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.注意:Buffer是非线程安全类. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO Buffer ...

  7. Java NIO Buffer(netty源码死磕1.2)

    [基础篇]netty源码死磕1.2:  NIO Buffer 1. Java NIO Buffer Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.Buffer缓冲区本质上是一块可 ...

  8. Java NIO Buffer说明

    Buffer 有3个重要的参数:位置(position).容量(capactiy).上限(limit) 位置(position): 写:当前缓冲区的位置,将从position的下一个位置写数据. 读: ...

  9. java.nio.Buffer源码阅读

    Java 自从 JDK1.4 起,对各种 I/O 操作使用了 Buffer 和 Channel 技术.这种更接近于操作系统的的底层操作使得 I/O 操作速度得到大幅度提升,下面引用一段<Java ...

随机推荐

  1. 洛谷4206/NOI2005T4 聪聪和可可 期望DP+记忆化搜索

    题意:给出n个点m条边的无向图,两个主角聪聪和可可开始分别在S点和T点.聪聪想吃掉可可,每次由匆匆先行动后来可可行动.聪聪的行动是选他到可可的最短路上的点走最多两步(如果最短路有几条就选编号最小的走) ...

  2. Sass--传一个不带值的参数

    Sass 的混合宏有一个强大的功能,可以传参,那么在 Sass 中传参主要有以下几种情形: A) 传一个不带值的参数 在混合宏中,可以传一个不带任何值的参数,比如: @mixin border-rad ...

  3. NotePad++安装compare插件(两个文件对比功能)

    首先百度搜索“notepad compare”,找到“Notepad++ Compare plugin download | SourceForge.net”,SourceForge提供了一个Comp ...

  4. Makefile中几种变量赋值运算符

    Makefile中几种变量赋值运算符: =      :最简单的赋值 :=     :一般也是赋值 以上这两个大部分情况下效果是一样的,但是有时候不一样. 用 = 赋值的变量,在被解析时他的值取决于最 ...

  5. CreateJS入门 -- 注释详细到爆炸(My Style)

    写在前面 首先,还是谢谢大家的支持,谢谢!记得在之前的文章中我说过自己算是一个半文艺程序员,也一直想着写一写技术性和其他偏文学性的文章.虽然自己的底子没有多么优秀,但总是觉得这个过程中可以督促自己去思 ...

  6. String、StringBuffer、StringBuilder详解

    String类 字符串广泛应用在java编程中,String类在java.lang包中,String类是final修饰的,不能被继承,String类对象创建后不能修改,由0或多个字符组成,包含在一对双 ...

  7. Oracle11g新建用户及用户表空间

    /* 建立数据表空间 */CREATE TABLESPACE SP_TAB DATAFILE '/u01/app/oracle/oradata/orcl/tab1_1.dbf' size 1024M ...

  8. MySQL执行计划示例

    以上示例来自尚硅谷!

  9. Codeforces 814C - An impassioned circulation of affection

    原题链接:http://codeforces.com/contest/814/problem/C 题意:有长度为n的一个字符串,q个询问,每个询问由数字m和字符c组成,问最多在字符串中替换m个字符,使 ...

  10. FPGA学习的一些误区

    转载自网络,作者不详. 我常年担任多个有关FPGA学习研讨的QQ群管理员,长期以来很多新入群的菜鸟们总是在重复的问一些非常简单但是又让新手困惑不解的问题.作为管理员经常要给这些菜鸟们普及基础知识,但是 ...