关于java NIO的总结

关于java NIO的总结:

import java.nio.IntBuffer;
import java.security.SecureRandom;

public class GetChannel {
    public static void main(String[] args) {
        // 分配内存大小为10的缓存区
        IntBuffer buffer = IntBuffer.allocate(10);
        // 往buffer里写入数据
        for (int i = 0; i < 5; ++i) {
            int randomNumber = new SecureRandom().nextInt(20);
            buffer.put(randomNumber);
        }
        // 将Buffer从写模式切换到读模式(必须调用这个方法)
       // buffer.flip();
        // 读取buffer里的数据
        while (buffer.hasRemaining()) {
            System.out.println(buffer.get());
        }
    }
}

最近,我在学习java NIO的时候,在看学习教程的时候,看到这样一段代码,遇到其中的buffer.filp()这个方法,让我很疑惑,首先我不知道他是干嘛的,然后在我的钻研下,搞懂了它的用途,原来他的作用是将写模式转化为读模式。而且这句代码必须加,不加的话,就会有一些问题让你摸不着头脑。

不相信的话,大家可以运行一下上面的代码,如果你不理解filp()方法的作用, 运行结果一定会让你大吃一惊,怎么会输出5个零呢??为什么!我也就不卖关子了。因为他输出的是buffer缓存区的后五个内存空间。

首先先看下基本概念(以下内容摘自blog:https://blog.csdn.net/u013096088/article/details/78638245)

这里有个关键的方法flip(),buffer读写转换全靠它来实现。看看这个方法做了什么,进入jdk源码,如下:

这里涉及的到Buffer的几个重要属性:position,limit,mark。所以,我们先得把这几个属性搞明白。

capacity,limit,position三个重要属性的含义

Buffer是特定基本类型元素的线性有限序列。除内容外,Buffer区的基本属性还包括capacity(容量)、limit(限制)和position(位置):

  • capacity是它所包含的元素的数量。缓冲区的容量不能为负并且不能更改。
  • limit是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量。
  • 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始终不变

而关于rewind方法,是在limit属性已经被设置合适的情况下使用的。也就是说这两个方法虽然都能够使指针返回到缓冲区的第一个位置,但是flip在调整指针之前,将limit属性设置为当前位置。

现在来强行解释一波把。

(发现上面的图是错的,最后一个空间应该是9,算了将错就错吧)首先,存入5个数据之后,postion
的位置在5,然后 limit, capacity 依然在9。如果不执行flip()方法,那么postion这些数据是不会变得,所
以输出的时候,从postion到capacity.即就是5个0,如果使用了flip()方法,那么 postion会回置为0,limit
回置为末尾元素空间的下一个不读取空间。即就是5,那么此时输出,即就是5个随机赋值的数了。
发布了63 篇原创文章 · 获赞 149 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/huijiaaa1/article/details/82935187
今日推荐