简述ByteBuffer的使用

简介

ByteBuffer是Java的NIO使用中最常用的缓冲区,它继承自Buffer是一个抽象类,在通过ByteBuffer.allocate(int capacity)创建时实则创建的是一个HeapByteBuffer,而这个HeapByteBuffer则是ByteBuffer的具体实现类.ByteBuffer内部还是通过数组进行数据的存放

Buffer中关键的四个属性

0<=mark<=position<=limit<=capacity
mark:上次标记的位置
position:当前指向的位置
limit:操作极限位置
capacity:初始容量,一旦指定不可更改(就是指定的内置byte[]的大小)
在初始创建时,mark=-1,position=0,limit=capacity,在get/put操作时position会相应的改变,在标记/重置操作时mark会相应的改变.

常用方法

get()方法

public ByteBuffer get(byte[] dst,int offset,int length)

    此方法就是读取length个字节到dst中从offset开始的位置,查看源码此方法最终调用如下
  public ByteBuffer get(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    checkBounds(paramInt1, paramInt2, paramArrayOfByte.length);
    if (paramInt2 > remaining())
      throw new BufferUnderflowException();
    System.arraycopy(this.hb, ix(position()), paramArrayOfByte, paramInt1, paramInt2);
    position(position() + paramInt2);
    return this;
  }
从方法内部可以看出首先检查各参数,就是通过checkBounds()保证传入的三个值>-1,然后判断缓冲区剩余可读字节数是否满足length个,不足则抛出异常,满足的话则复制指定数目的数据到指定数组dst的指定位置上.最后将当前位置向前移动length个.
此方法使用时注意要length<=remaining()否则就会抛异常
public ByteBuffer get(byte[] dst)f方法使用雷同,实则还是调用的get(byte[] dst,0,dst.length)

put()方法

public ByteBuffer put(byte[] src,int offset, int length)

    此方法就是读取源数组src中offset开始的length个字节数据到缓冲区中,查看源码最终调用方法如下
  public ByteBuffer put(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
  {
    checkBounds(paramInt1, paramInt2, paramArrayOfByte.length);
    if (paramInt2 > remaining())
      throw new BufferOverflowException();
    System.arraycopy(paramArrayOfByte, paramInt1, this.hb, ix(position()), paramInt2);
    position(position() + paramInt2);
    return this;
  }
  其实过程与get基本一直,首先判断参数是否合法即>-1,然后判断剩余空间是否足以接收length个字节数据,否则抛出异常,是则接收数据即将源数组中指定数据copy到内置的数组中去,同时将position位置增加length.

flip()方法

public final Buffer flip()

通常所说的切换到读模式,flip()方法会将limit置为position,position置0,mark置为-1,具体实现如下
 public final Buffer flip(){
    this.limit = this.position;
    this.position = 0;
    this.mark = -1;
    return this;
 }

clear()方法

public final Buffer clear()

而clear方法则是将position置为0,limit置为capcity,mark置为-1,注意并没有清空数据仍然可以进行读取,具体实现如下
public final Buffer clear(){
    this.position = 0;
    this.limit = this.capacity;
    this.mark = -1;
    return this;
}

mark()方法

public final Buffer mark()

  就是记录当前position的位置,具体实现如下
  public final Buffer mark()
  {
    this.mark = this.position;
    return this;
  }

reset()方法

public final Buffer reset()

  此方法的目的就是将position的位置重置为上次mark的位置,注意若之前没有mark即mark值为-1时则会抛出异常.具体实现如下
  public final Buffer reset()
  {
    int i = this.mark;
    if (i < 0)
      throw new InvalidMarkException();
    this.position = i;
    return this;
  }

猜你喜欢

转载自blog.csdn.net/Noonebirdyou/article/details/78634979