缓冲区视图

ByteBuffer类的另外一个常见的使用方式是在一个已有的ByteBuffer类的对象上创建出各种不同的视图。这些视图和它所基于的ByteBuffer类的对象共享同样的存储空间,但是提供额外的实用功能。在功能上,ByteBuffer类的视图与它所基于的ByteBuffer类的对象之间的关系类似于3.1.4节介绍的过滤流和它所包装的流的关系。正因为这种共享存储空间的特性,在视图中对数据所做的修改会反映在原始的ByteBuffer类的对象中。

最常见的ByteBuffer类的视图是转换成对基本数据类型进行操作的缓冲区对象。这些缓冲区包括CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer和DoubleBuffer等Java类。从这些缓冲区的类名就可以知道所操作的数据类型。ByteBuffer类提供了对应的方法来完成相应的转换,如asIntBuffer方法在当前ByteBuffer类的对象的基础上创建一个新的IntBuffer类的视图。新创建的视图和原始的ByteBuffer类的对象所共享的不一定是全部的空间,而只是从ByteBuffer类的对象中的当前读写位置到读写限制之间的可用空间。在这个空间范围内,不论是在ByteBuffer类的对象中还是在作为视图的新缓冲区中,对数据所做的修改,对另一个来说都是可见的。除了数据本身之外,两者的读写位置、读写限制和标记位置等都是相互独立的。在代码清单3-6中,创建视图的时候,两者所共享的是序号4~32的空间。在IntBuffer类的对象中所做的修改,对于原始的ByteBuffer类的对象也是可见的。ByteBuffer类的基本数据类型视图在开发中的使用场景比较多,这主要是因为很多I/O相关的API都使用ByteBuffer类作为参数类型,而ByteBuffer类的视图可以很方便地对内容进行操作。

代码清单3-6 字节缓冲区的视图

  1. public void viewBuffer() {  
  2.     ByteBuffer buffer = ByteBuffer.allocate(32);  
  3.     buffer.putInt(1); //读取位置为4  
  4.     IntBuffer intBuffer = buffer.asIntBuffer();  
  5.     intBuffer.put(2);  
  6.     int value = buffer.getInt(); //值为2  

除了基本类型的缓冲区视图之外,另外一类视图是类型相同的ByteBuffer类的对象。通过slice方法可以创建一个当前ByteBuffer类的对象的视图,其行为类似于通过asIntBuffer方法创建的视图,只不过得到的是ByteBuffer类的对象。而duplicate方法则用来完全复制一个ByteBuffer类的对象。这个方法与slice方法的区别在于,duplicate方法并不考虑ByteBuffer类的对象的当前读写位置和读写限制,只是简单地全部复制。方法asReadOnlyBuffer的行为类似于duplicate方法,只不过得到的ByteBuffer类的对象是只读的,不能执行写入操作。

对于其他基本类型的缓冲区来说,除了通过ByteBuffer类的视图来创建之外,也可以通过对应类的allocate方法来直接创建。这些缓冲区类与ByteBuffer类的最显著区别在于,其中的容量、读写位置和读写限制都是根据基本类型的个数来计算的,而不是根据字节数计算的。如通过“IntBuffer.allocate(32)”创建的整型缓冲区的容量是32个整数,而不是32个字节。另外,不能直接创建出除ByteBuffer类之外的其他类型的直接缓冲区,只能先创建ByteBuffer类型的直接缓冲区,再创建相应的基本类型的视图。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值