在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. 98-基于FPGA Spartan6 的双路光纤PCIe采集卡(2路光纤卡) 光纤PCIe卡

    1.板卡概述 板卡采用xilinx Spartan6系列芯片,支持 PCI Express Base Specification 1.1 x1.内含丰富的逻辑资源和存储单元,板卡FPGA外接双片32M ...

  2. 二、Ajax请求MVC中数据查询表返回datatable

    一.Ajax请求MVC中数据查询表返回datatable 解决方式 返回list

  3. Redis和Ehcached的区别

    Redis 属于独立的运行程序,需要单独安装后,使用JAVA中的Jedis来操纵.因为它是独立,所以如果你写个单元测试程序,放一些数据在Redis中,然后又写一个程序去拿数据,那么是可以拿到这个数据的 ...

  4. SYSAUX表空间满,

    step1.  确认到底是哪个段占用了sysaux空间: select segment_name,sum(bytes)/1024/1024 from dba_segments where tables ...

  5. 【串线篇】加谈数据库之连接join

    主题:内连接.左连接(左外连接).右连接(右外连接) 建表语句: CREATE TABLE `a_table` (  `a_id` int(11) DEFAULT NULL,  `a_name` va ...

  6. class反编译

    JD-GUI:http://java-decompiler.github.io/ 离线包在我的文件 下载安装,file选择class文件即可浏览 反编译代码与源码去掉注释后的代码比较接近,虽然比源码损 ...

  7. 什么是NFA(不确定的有穷自动机)和DFA(确定的有穷自动机)

    本节知识点是<编译原理>第三章-词法分析,学习参考教材为清华大学出版社<编译原理>第三版: 前情提要: 字母表∑1和∑2的乘积( product): ∑1∑2 ={ab|a ∈ ...

  8. mysql创建数据库用户

    连接mysql cmd--> mysql -hlocalhost -uroot -pmypassword 退出mysql mysql> quit 也可用exit或者 \q ======== ...

  9. JS 判断undefined

    tax !== underfined underfined 是判断的是类型的结果, 如果加typeof后是字符串类型 写法:typeof(tax) !== "underfined" ...

  10. Spring Security 安全认证

    Spring Boot 使用 Mybatis 依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> ...