李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
03.NIO之bytebuffer内部结构和方法
Leefs
2022-05-25 PM
896℃
0条
[TOC] ### 一、bytebuffer内部结构 #### 1.1 属性介绍 **Bytebuffer有以下重要属性:** + **capacity(容量)**:缓冲区的容量。通过构造函数赋予,一旦设置,无法更改。 + **position(指针)**:读写指针,记录数据读写的位置,缓冲区的位置不能为负,并且**不能大于limit**。 + **limit(读写限制)**:缓冲区的界限。位于limit 后的数据不可读写。缓冲区的限制不能为负,并且**不能大于其容量**。 #### 1.2 结构 + **写模式** 当缓冲区刚创建成功时 ![03.NIO之bytebuffer内部结构和方法01.png](https://lilinchao.com/usr/uploads/2022/05/3935100654.png) 写模式下,position 是写入位置,limit 等于容量。 下图表示写入了 4 个字节后的状态: ![03.NIO之bytebuffer内部结构和方法02.png](https://lilinchao.com/usr/uploads/2022/05/2417444730.png) Position移动到第5个字节开始位置 + **读模式** flip动作发生后,position切换为读取位置,limit切换为读取限制 ![03.NIO之bytebuffer内部结构和方法03.png](https://lilinchao.com/usr/uploads/2022/05/1728412666.png) + position重新赋值到开始位置,因为读取数据从开始位置开始读取 + limit被赋值为position写入时的最后位置,作为数据读取的最终位置 读取4个字节后,状态如下图: ![03.NIO之bytebuffer内部结构和方法04.png](https://lilinchao.com/usr/uploads/2022/05/4205227856.png) + 当position位置与limit位置相同时,数据读取结束。 + **数据未读取完重新切换到写模式时** compact 方法,是把未读完的部分向前压缩,然后切换至写模式 ![03.NIO之bytebuffer内部结构和方法05.png](https://lilinchao.com/usr/uploads/2022/05/2245375026.png) ### 二、ByteBuffer常见方法 + ##### **put()** **描述:**可以将一个数据放入到缓冲区中。 进行该操作后,postition的值会+1,指向下一个可以放入的位置。capacity = limit ,为缓冲区容量的值。 ![03.NIO之bytebuffer内部结构和方法06.png](https://lilinchao.com/usr/uploads/2022/05/293181828.png) + ##### **flip()** **描述**:用来**切换对缓冲区的操作模式**,由写->读 / 读->写 进行该操作后: + 如果是写模式->读模式,position = 0 , limit 指向最后一个元素的下一个位置,capacity不变; + 如果是读模式->写模式,则恢复为put()方法中的值。 ![03.NIO之bytebuffer内部结构和方法07.png](https://lilinchao.com/usr/uploads/2022/05/4207702593.png) + ##### **get()** **描述**:该方法会读取缓冲区中的一个值 进行该操作后,position会+1,如果超过了limit则会抛出异常 ![03.NIO之bytebuffer内部结构和方法08.png](https://lilinchao.com/usr/uploads/2022/05/3533719035.png) *注意:get(i)方法不会改变position的值* + ##### **rewind()** **描述**:该方法**只能在读模式下使用** rewind()方法后,会恢复position、limit和capacity的值,变为进行get()前的值 ![03.NIO之bytebuffer内部结构和方法09.png](https://lilinchao.com/usr/uploads/2022/05/1369941017.png) + ##### clean() 描述:会将缓冲区中的各个属性恢复为最初的状态,position = 0, capacity = limit **此时缓冲区的数据依然存在**,处于“被遗忘”状态,下次进行写操作时会覆盖这些数据 ![03.NIO之bytebuffer内部结构和方法10.png](https://lilinchao.com/usr/uploads/2022/05/2141478096.png) + ##### **mark()/reset()** **描述**:mark 是在读取时,做一个标记,即使 position 改变,只要调用 reset 就能回到 mark 的位置 **mark()**:将postion的值保存到mark属性中 **reset()**:将position的值改为mark中保存的值 *注意:rewind 和 flip 都会清除 mark 位置* + ##### compact() **描述**:compact会把未读完的数据向前压缩,然后切换到写模式 数据前移后,原位置的值并未清零,写时会**覆盖**之前的值 ![03.NIO之bytebuffer内部结构和方法11.png](https://lilinchao.com/usr/uploads/2022/05/1868787814.png) *注意:此方法为ByteBuffer的方法,而不是Buffer的方法* **clear()和compact()方法对比:** clear只是对position、limit、mark进行重置,而compact在对position进行设置,以及limit、mark进行重置的同时,还涉及到数据在内存中拷贝(会调用arraycopy)。**所以compact比clear更耗性能。**但compact能保存你未读取的数据,将新数据追加到为读取的数据之后;而clear则不行,若你调用了clear,则未读取的数据就无法再读取到了 **需要根据情况来判断使用哪种方法进行模式切换** *附参考文章:* *《黑马程序员Netty教程》*
标签:
Netty
,
NIO
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2088.html
上一篇
02.NIO之bytebuffer基本使用
下一篇
04.NIO之bytebuffer常见方法演示
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
Redis
Sentinel
国产数据库改造
Http
Golang
Nacos
SpringBoot
NIO
MyBatis
随笔
Git
Spark Core
gorm
数据结构
高并发
Flume
FileBeat
算法
设计模式
DataX
MyBatis-Plus
容器深入研究
查找
JavaSE
Hbase
Typora
Elastisearch
VUE
Java工具类
Python
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞