关于ByteBuffer使用解释
发布日期:2021-07-01 01:39:54
浏览次数:3
分类:技术文章
本文共 2385 字,大约阅读时间需要 7 分钟。
转载自
之前看过相关的ByteBuffer的使用,但是问题是那时还年轻,所以现在有点老了,因此,忘记了,所以决心看源代码了解一番----故作此篇文章。
查看ByteBuffer的API,看的我是一头雾水,搞不清什么mark、position、limit、flip、reset几个的用法,先看下面的例子:
String str = "helloWorld"; ByteBuffer buff = ByteBuffer.wrap(str.getBytes()); System.out.println("position:"+buff.position()+"\t limit:"+buff.limit()); //读取两个字节 buff.get(); buff.get(); System.out.println("position:"+ buff.get(buff.position())+"\t limit:"+buff.limit()); buff.mark(); System.out.println("position:"+buff.position()+"\t limit:"+buff.limit()); buff.flip(); System.out.println("position:"+buff.position()+"\t limit:"+buff.limit());
输出结果:
position:0 limit:10position:2 limit:10position:2 limit:10position:0 limit:2
我们以每位开发人员熟悉的”helloworld“,用ByteBuffer将字符串包装,由于ByteBuffer是一个抽象类,通过wrap包装的对象将实际返回的是一个HeapByteBuffer对象。由此可知HeapByteBuffer是ByteBuffer的子类,同样的ByteBuffer又是Buffer抽象类的子类。以上提到的mark、position、limit、flip、reset都是出自于Buffer这个抽象类。
下面我们来解析几个方法的,当我们调用了wrap方法后Buffer中初始化的结构是:
注释:
m:mark;
p:position;
L:limit;
初始情况下mark是指向第一个元素之前的的即-1,postion为指向第一个元素为0.而Limit是被赋值为byte[]的长度。
因此这就是打印结果的第一行。
m | p | L | |||||||||
-1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
H | E | L | L | O | W | O | R | L | D |
当我们连续调用两次get()方法获得两个个字节,每次调用都会触发position++操作,那么此时position就会移动到index = 2的的地方,而这个时候Limit和mark是不会发生变化的。如果将读取的两个字节打印会是H和E,因此执行结果第二行会有 position:2 limit:10结果.
m、p | L | ||||||||||
-1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
H | E | L | L | O | W | O | R | L | D |
读取完毕后我们使用mark,这个时候mark会从-1移动到2和position指向同一个元素,可以看见Limit是不会发生改变的。
m | p | L | |||||||||
-1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
H | E | L | L | O | W | O | R | L | D |
使用了mark标记的当前的position后,如果们调用flip,这个时候Limit就会指向position的位置,并将mark和position还原为初始值。这样就知道了limit当前的就为2,什么意思呢?就是说当前可以读的字节数是2。
我们可以尝试一下如下代码:
System.out.println((char)buff.get()+""+(char)buff.get());
输出结果:he
貌似这也没什么稀奇的,如果你在代码换成
// System.out.println((char)buff.get()+""+(char)buff.get() System.out.println((char)buff.get()+""+(char)buff.get()+""+(char)buff.get());
输出结果:
limit:10 Exception in thread "main" java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:474) at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:117) at com.taobao.moxing.notify.Main.main(Main.java:33)position:2 limit:10 position:2 limit:10 position:0 limit:2 为什么会抛异常呢?原因是limit的含义就想一个窗口,你当前能读到的数据就是当前窗口限制的(本例中即为2),如果这个窗口之外的所有元素都是不可读的。至此我想你和我就应该明白这几个参数的含义了吧。
而至于reset方法,它是将当前的position设置为0,
rewind是将mark重置为-1,position重置为0;
clear方法是真正的重置,将mark=-1,position=0,limit=capacity(即当前buffer的容量)
转载地址:https://maokun.blog.csdn.net/article/details/80630438 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月26日 17时31分30秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
uml类图图形快速入门介绍
2019-05-01
jsp中的contentType与pageEncoding的区别和作用
2019-05-01
Meta标签详解
2019-05-01
编译指令page覆盖meta设置
2019-05-01
一个页面引入另一个页面时,contentType 应保持一致
2019-05-01
Logback学习
2019-05-01
Apache Commons:功能齐全的通用Java组件
2019-05-01
第2个java程序的心得
2019-05-01
第三次java学习心得
2019-05-01
第四次学习java
2019-05-01
Django入门
2019-05-01
Nameko中文教程
2019-05-01
python built-in function summary
2019-05-01
对于git/热部署/创建maven工程的小记录
2019-05-01
在jsp中调用本地外部json文件的解决方法
2019-05-01
ECharts is not Loaded解决方案
2019-05-01
ECharts地图显示不完整,只显示南海诸岛问题
2019-05-01
echarts is not defined解决方案
2019-05-01
require is not defined
2019-05-01