码迷,mamicode.com
首页 > 其他好文 > 详细

NIO入门之缓冲区Buffer

时间:2020-07-12 16:16:41      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:核心   wrap   RKE   cep   获取数据   数组初始化   math   状态   也会   

缓存区 Buffer 是数据容器

技术图片

  • ByteBuffer 可以存储除了 boolean 以外的其他 7 种Java基本数据类型,如 getInt、putInt
  • Buffer 是抽象类,它有除了 Boolean 以外的其他 7 种Java基本数据类型子类,如IntBuffer

缓存区的初始化

⑴ 静态方法 allocate:初始化一个指定容量的缓存区
技术图片

解释一下图例:
1.数组下标:数字(1,2,3,4,5)表示数组下标
1.数组:灰色长方形内表示真实有效的数组。
2.数组元素:数字所在的白色黑边正方形表示数组元素,可以通过例如 array[0] 来获取数组元素。但是注意,图中没有明确指定数组元素的值是什么。
3.虚拟下标:其中 -16 是虚拟的下标位置,如果使用这2个下标取值( array[-1] 或者 array[6] )会抛出 IndexOutOfBoundsException

⑵ 静态方法 wrap:把一个数组初始化成一个缓存区

  • 如果是只把数组 array 作为 wrap 的参数,那么效果和 allocate 类似。但是,修改数组中的值,等同于修改缓存区的值。
  • 如果除了数组引用 array 外,还有 offsetlength 来指定子数组的开始位置和子数组的大小。效果如下图:

技术图片

  • 灰色的部分就是数组参数 array
  • 虚线框的部分表示从数组中划出的 子数组

缓存区存储数据

技术图片

  • put() 填充一个新的元素到数组中
  • 当前位置右移(position++)

缓冲区获取数据

技术图片

  • get() 获取当前位置的元素
  • 当前位置右移(position++)

核心操作

flip 操作

由写模式 转换为> 读模式
技术图片

  • limit = position,限制转到原先的 position 位置
  • position = 0,游标归零
  • mark = -1,标记清空

注意:
虽然,flip 的中文含义是 “翻动”,但是连续调用 flip 不能实现 写模式 -> 读模式 -> 写模式!
连续调用 flip 之后,postion == limit == 0。
因此,继续调用 get() 会抛出 读取超限 BufferUnderflowException ,调用 put() 会抛出 写入超限 BufferOverflowException

clear 操作

重新回到初始化状态,重新进入写模式
技术图片

  • limit = capacity,限制回归到容器容量
  • position = 0,游标归零
  • mark = -1,标记清空

注意
clear 实际并不会清理数据,而是调整 limit、position、mark 指向的位置

mark 操作

技术图片

  • mark = position,记录下当前位置

使用场景
替换一段内容:添加标记,以便后续调用 reset() 将 position 回到标记。

reset 操作

技术图片

  • position = mark,当前位置回到标记位置

注意
技术图片

  • mark < 0 抛出无效标记异常。说明必须要先 mark() 才能调用 reset()

rewind 操作

技术图片

  • position = 0,当前位置归零
  • mark = -1,清除标记位置

剩余空间与超限异常

剩余空间

\[0 <= 标记 <= 位置 <= 限制 <= 容量 \]

其中,

\[remaining = limit - position \]

remaining 表示剩余空间大小。hasRemaining() 用来查询是否还有剩余空间。

读取超限

技术图片

  • get 读取数据时,如果 position >= limit,抛出 BufferUnderflowException 异常

写入超限

技术图片

  • put 写入数据时,如果 position >= limit,抛出 BufferOverflowException 异常

注意
如果是使用 wrap 初始化的缓冲区,即使没有到达容器容量 capacity,也会报错,因为此时 limit < capacity
技术图片

总结:

  • Buffer缓冲区是数据容器,可以用于读 get() 也可以用于写 put()。
  • flip() 可以从写模式切换到读模式
  • clear() 可以回到初始化状态
  • mark() 和 reset() 需要配合使用,主要用于 替换某段内容
  • 无论是读取超限还是写入超限,条件都是 position >= limit。即 如果进行接下来的读或者写操作,当前位置都将超过限制。

NIO入门之缓冲区Buffer

标签:核心   wrap   RKE   cep   获取数据   数组初始化   math   状态   也会   

原文地址:https://www.cnblogs.com/kendoziyu/p/java-nio-buffer.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!