美文网首页JDK源码
java.nio.ByteBuffer源码解析

java.nio.ByteBuffer源码解析

作者: sunpy | 来源:发表于2018-02-27 22:06 被阅读6次

    所属包

    package java.nio; 
    

    继承与实现关系

    public abstract class ByteBuffer  
        extends Buffer  
        implements Comparable<ByteBuffer> 
    

    属性

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

    构造器

    /** 
     * 创建一个带有临时备忘标记变量、读写的开始位置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);  
       }  
    

    方法

        /** 
         * 分配一个新的指定容量的缓冲区 
         */  
        public static ByteBuffer allocateDirect(int capacity) {  
            return new DirectByteBuffer(capacity);  
        }  
      
        /** 
         * 分配一个新的指定容量字节缓冲区 
         */  
        public static ByteBuffer allocate(int capacity) {  
            //如果容量小于0,那么抛出非法参数异常  
            if (capacity < 0)  
                throw new IllegalArgumentException();  
            //返回一个堆字节缓冲区 ,将缓冲区分配在jvm中的heap堆上
            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;  
        }  
    
    

    ---------------------------该源码为jdk1.7版本的

    相关文章

      网友评论

        本文标题:java.nio.ByteBuffer源码解析

        本文链接:https://www.haomeiwen.com/subject/ygcvxftx.html