关于ByteBuffer使用解释

系统 1353 0

之前看过相关的ByteBuffer的使用,但是问题是那时还年轻,所以现在有点老了,因此,忘记了,所以决心看源代码了解一番----故作此篇文章。

 

查看ByteBuffer的API,看的我是一头雾水,搞不清什么mark、position、limit、flip、reset几个的用法,先看下面的例子:

Java代码     收藏代码
  1.      String str =  "helloWorld" ;  
  2.         ByteBuffer buff  = ByteBuffer.wrap(str.getBytes());  
  3.         System.out.println( "position:" +buff.position()+ "\t limit:" +buff.limit());  
  4.          //读取两个字节   
  5.         buff.get();  
  6.         buff.get();  
  7.         System.out.println( "position:" + buff.get(buff.position())+ "\t limit:" +buff.limit());  
  8.         buff.mark();  
  9.         System.out.println( "position:" +buff.position()+ "\t limit:" +buff.limit());  
  10.         buff.flip();  
  11.         System.out.println( "position:" +buff.position()+ "\t limit:" +buff.limit());<span style= "white-space: pre;" >    </span>  
Java代码     收藏代码
  1. <pre name= "code"   class = "java" >输出结果:  
  2. position: 0   limit: 10   
  3. position: 2   limit: 10   
  4. position: 2   limit: 10   
  5. position: 0   limit: 2   
  6. </pre>  
  7.    
  我们以每位开发人员熟悉的”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。
我们可以尝试一下如下代码:
 
Java代码     收藏代码
  1. System.out.println(( char )buff.get()+ "" +( char )buff.get());  
    输出结果:he
    貌似这也没什么稀奇的,如果你在代码换成
 
Java代码     收藏代码
  1. // System.out.println((char)buff.get()+""+(char)buff.get()   
  2.    System.out.println(( char )buff.get()+ "" +( char )buff.get()+ "" +( char )buff.get());  
Java代码     收藏代码
  1. 输出结果:<pre name= "code"   class = "java" >position: 0     limit: 10   
  2. Exception in thread  "main"  java.nio.BufferUnderflowException  
  3.     at java.nio.Buffer.nextGetIndex(Buffer.java: 474 )  
  4.     at java.nio.HeapByteBuffer.get(HeapByteBuffer.java: 117 )  
  5.     at com.taobao.moxing.notify.Main.main(Main.java: 33 )position: 2     limit: 10   
  6. position: 2    limit: 10   
  7. position: 0    limit: 2   
  8. </pre>  
   为什么会抛异常呢?原因是limit的含义就想一个窗口,你当前能读到的数据就是当前窗口限制的(本例中即为2),如果这个窗口之外的所有元素都是不可读的。至此我想你和我就应该明白这几个参数的含义了吧。
    而至于reset方法,它是将当前的position设置为0,
     rewind是将mark重置为-1,position重置为0;
     clear方法是真正的重置,将mark=-1,position=0,limit=capacity(即当前buffer的容量)

关于ByteBuffer使用解释


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论