java.nio.ByteBuffer字节缓冲区源码解析

1.Buffer的解析

http://blog.csdn.net/ya_1249463314/article/details/79205409

2.所属包

package java.nio;

3.继承与实现关系

public abstract class ByteBuffer
    extends Buffer
    implements Comparable<ByteBuffer>


4.常用变量

//堆缓冲数组
final byte[] hb;                 //字节数组偏移量
    final int offset;
	//堆缓冲是否可读
    boolean isReadOnly;

5.构造器

 /**
	 * 创建一个带有临时备忘标记变量、读写的开始位置pos、
	 * 读写的最大容量lim、缓冲区的最大容量cap、字节数组、偏移量的构造器
	 */
    ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
        super(mark, pos, lim, cap);
        this.hb = hb;
        this.offset = offset;
    }

    /**
	 * 创建一个带有临时备忘标记变量mark、读写的开始位置pos、
	 * 读写的最大容量lim、缓冲区的最大容量cap,字节数组为null,数组偏移量为0的缓冲区
	 */
    ByteBuffer(int mark, int pos, int lim, int cap) { 
        this(mark, pos, lim, cap, null, 0);
    }

6.常用的方法

/**
     * 分配一个新的指定容量的缓冲区
     */
    public static ByteBuffer allocateDirect(int capacity) {
        return new DirectByteBuffer(capacity);
    }

    /**
     * 分配一个新的指定容量字节缓冲区
     */
    public static ByteBuffer allocate(int capacity) {
		//如果容量小于0,那么抛出非法参数异常
        if (capacity < 0)
            throw new IllegalArgumentException();
		//返回一个堆字节缓冲区
        return new HeapByteBuffer(capacity, capacity);
    }

    /**
     * 封装字节数组到缓冲区中  
	 * 输入参数为字节数组,数组的偏移量,长度
     */
    public static ByteBuffer wrap(byte[] array,int offset, int length) {
        try {
            return new HeapByteBuffer(array, offset, length);
        } catch (IllegalArgumentException x) {
            throw new IndexOutOfBoundsException();
        }
    }

    /**
     * 封装字节数组到缓冲区中
     */
    public static ByteBuffer wrap(byte[] array) {
        return wrap(array, 0, array.length);
    }

    /**
     * 创建新的字节缓冲区,其内容是此缓冲区内容的共享子序列。
     */
    public abstract ByteBuffer slice();

    /**
     * 创建共享此缓冲区内容的新的字节缓冲区。
     */
    public abstract ByteBuffer duplicate();

    /**
     * 创建共享此缓冲区内容的新的只读字节缓冲区。
     */
    public abstract ByteBuffer asReadOnlyBuffer();

    /**
     * 读取缓冲区中的字节
     */
    public abstract byte get();

    /**
     * 将给定的字节写入此缓冲区的当前位置,然后该位置递增。
     */
    public abstract ByteBuffer put(byte b);

    /**
     * 从指定的索引处获取字节
     */
    public abstract byte get(int index);

    /**
     * 将给定字节写入此缓冲区的给定索引处。 
	 * index为指定的索引,b为给定的字节
     */
    public abstract ByteBuffer put(int index, byte b);

    /**
     * 将缓冲区中的数据获取复制到输入的字节数组中,赋值的开始偏移量为offset,赋值的长度为length
     */
    public ByteBuffer get(byte[] dst, int offset, int length) {
		//检查下标是否超出
        checkBounds(offset, length, dst.length);
		//缓冲区Buffer的剩余元素的数量小于获取的长度,抛出缓冲区溢出错误。
        if (length > remaining())
            throw new BufferUnderflowException();
		//数组的偏移量加上长度为数组尾元素的下标
        int end = offset + length;
		//从数组的偏移量开始到数组的尾下标处,开始遍历获取元素
        for (int i = offset; i < end; i++)
            dst[i] = get();
		//返回当前的字节缓冲区
        return this;
    }

    /**
     * 将缓冲区中的数据获取复制到输入的字节数组中
     */
    public ByteBuffer get(byte[] dst) {
        return get(dst, 0, dst.length);
    }

    /**
     * 将输入的指定缓冲区中的元素转移到另一个缓冲区中
     */
    public ByteBuffer put(ByteBuffer src) {
		//如果指定输入的缓冲区就是当前的缓冲区,那么抛出非法参数异常。
        if (src == this)
            throw new IllegalArgumentException();
		//获取输入的缓冲区中存放元素的数量
        int n = src.remaining();
        if (n > remaining())
            throw new BufferOverflowException();
		//循环遍历输入缓冲区中的元素将其放到当前的缓冲区中
        for (int i = 0; i < n; i++)
            put(src.get());
		//返回当前的缓冲区
        return this;
    }

    /**
     * 将指定的字节数组中的一段数据放到字节缓冲区中
     */
    public ByteBuffer put(byte[] src, int offset, int length) {
		//检查下标是否超出
        checkBounds(offset, length, src.length);
		//缓冲区Buffer的剩余元素的数量小于获取的长度,抛出缓冲区溢出错误。
        if (length > remaining())
            throw new BufferOverflowException();
		//输入的字节数组的尾元素的下标
        int end = offset + length;
		//循环遍历缓冲区中的元素放入到当前的缓冲区中
        for (int i = offset; i < end; i++)
            this.put(src[i]);
		//返回当前的字节缓冲区
        return this;
    }

    /**
     * 将指定的字节数组中的数据放到字节缓冲区中
     */
    public final ByteBuffer put(byte[] src) {
        return put(src, 0, src.length);
    }

    /**
     * 缓冲区是否有一个可访问的字节数组支持
     */
    public final boolean hasArray() {
        return (hb != null) && !isReadOnly;
    }

    /**
     * 获取字节数组
     */
    public final byte[] array() {
        if (hb == null)
            throw new UnsupportedOperationException();
        if (isReadOnly)
            throw new ReadOnlyBufferException();
        return hb;
    }

    /**
     * 获取数组的偏移量
     */
    public final int arrayOffset() {
        if (hb == null)
            throw new UnsupportedOperationException();
        if (isReadOnly)
            throw new ReadOnlyBufferException();
        return offset;
    }

    public abstract ByteBuffer compact();

    /**
     * 判断缓冲区是否是直接缓冲区
     */
    public abstract boolean isDirect();

    /**
     * 返回缓冲区的hash值
     */
    public int hashCode() {
        int h = 1;
        int p = position();
        for (int i = limit() - 1; i >= p; i--)
            h = 31 * h + (int)get(i);
        return h;
    }

	//比较输入的缓冲区中的字节和当前的缓冲区中的字节是否都相同,如果都相同就返回0
    public int compareTo(ByteBuffer that) {
        int n = this.position() + Math.min(this.remaining(), that.remaining());
        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
            int cmp = compare(this.get(i), that.get(j));
            if (cmp != 0)
                return cmp;
        }
        return this.remaining() - that.remaining();
    }

	//比较两个字节
    private static int compare(byte x, byte y) {
        return Byte.compare(x, y);
    }
   
    boolean bigEndian                                   // package-private
        = true;
    boolean nativeByteOrder                             // package-private
        = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);

	//获取此缓冲区的字节顺序
    public final ByteOrder order() {
        return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
    }

	//修改此缓冲区的字节顺序
    public final ByteBuffer order(ByteOrder bo) {
        bigEndian = (bo == ByteOrder.BIG_ENDIAN);
        nativeByteOrder =
            (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
        return this;
    }





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值