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

java.nio.HeapByteBuffer源码解析

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

    所属包

    package java.nio;
    

    继承与实现关系

    class HeapByteBuffer extends ByteBuffer
    

    HeapByteBuffer解析

    HeapByteBuffer堆字节缓冲区是将缓冲区分配在jvm中的heap堆上,其实现本身是一个字节数组,实际上该数组分配在操作系统中的用户内存,而不是内核内存。

    构造器

        /**  
         * 指定参数构造器,  
         * 初始化标记mark为-1,设置堆缓冲数组空间大小为cap,字节数组的偏移量为0  
         */  
        HeapByteBuffer(int cap, int lim) {              
            super(-1, 0, lim, cap, new byte[cap], 0);  
        }  
    
        /**  
         * 指定参数构造器,  
         * 初始化标记mark为-1,设置读写的开始位置为off,读写的最大容量为off+len  
         * 设置缓冲区的最大容量为buf字节数组的容量,设置堆缓冲数组为buf,字节数组的偏移量为0  
         */  
        HeapByteBuffer(byte[] buf, int off, int len) {   
            super(-1, off, off + len, buf.length, buf, 0);  
        }  
    
        /**  
         * 指定参数构造器,  
         * 初始化标记为mark,设置读写的开始位置为pos,读写的最大容量为lim  
         * 设置缓冲区的最大容量为cap,设置堆缓冲数组为buf,字节数组的偏移量为off  
         */  
        protected HeapByteBuffer(byte[] buf,  
                                       int mark, int pos, int lim, int cap,  
                                       int off)  
        {  
            super(mark, pos, lim, cap, buf, off);  
        }  
    

    方法

        /**  
         * 创建新的堆字节缓冲区,其内容是此缓冲区内容的共享子序列  
         * 标记mark为-1,读写开始位置为0,读写的最大容量为缓冲区剩余元素的容量  
         * 缓冲区的最大容量为缓冲区剩余元素的容量,字节数组的偏移量为当前读写位置加上原字节数组的偏移量  
         */  
        public ByteBuffer slice() {  
            return new HeapByteBuffer(hb,  
                                            -1,  
                                            0,  
                                            this.remaining(),  
                                            this.remaining(),  
                                            this.position() + offset);  
        }  
      
        /**  
         * 创建共享此缓冲区内容的新的堆字节缓冲区  
         * 标记mark为当前的缓冲区的mark,读写的开始位置为当前缓冲区的pos,  
         * 读写的最大容量为当前缓冲区的lim,缓冲区的最大容量为当前缓冲区的最大容量cap  
         * 数组的偏移量为当前数组的偏移量offset  
         */  
        public ByteBuffer duplicate() {  
            return new HeapByteBuffer(hb,  
                                            this.markValue(),  
                                            this.position(),  
                                            this.limit(),  
                                            this.capacity(),  
                                            offset);  
                                              
        }  
      
        /**  
         * 创建一个只读的堆字节缓冲区  
         * 标记mark为当前的缓冲区的mark,读写的开始位置为当前缓冲区的pos,  
         * 读写的最大容量为当前缓冲区的lim,缓冲区的最大容量为当前缓冲区的最大容量cap  
         * 数组的偏移量为当前数组的偏移量offset  
         */  
        public ByteBuffer asReadOnlyBuffer() {  
      
            return new HeapByteBufferR(hb,  
                                         this.markValue(),  
                                         this.position(),  
                                         this.limit(),  
                                         this.capacity(),  
                                         offset);  
                                           
        }  
      
        //设置读取字节数组的偏移量为i+offset  
        protected int ix(int i) {  
            return i + offset;  
        }  
      
        //获取下一个字节  
        public byte get() {  
            return hb[ix(nextGetIndex())];  
        }  
      
        //获取指定下标的字节  
        public byte get(int i) {  
            return hb[ix(checkIndex(i))];  
        }  
      
        //将当前的缓冲区中的字节数组从position加1中开始复制到输入的字节数组dst中  
        public ByteBuffer get(byte[] dst, int offset, int length) {  
            //检查下标是否越界  
            checkBounds(offset, length, dst.length);  
            //检查缓冲区是否溢出  
            if (length > remaining())  
                throw new BufferUnderflowException();  
            //将缓冲区中的字节数组的指定位置position+offset开始复制字节到指定的dst字节数组  
            System.arraycopy(hb, ix(position()), dst, offset, length);  
            //设置读写的开始位置为position+length  
            position(position() + length);  
            //返回当前的字节缓冲区  
            return this;  
        }  
      
        //缓冲区是否为直接在内核上缓冲区,返回false,因为现在是在jvm堆字节缓冲区  
        public boolean isDirect() {  
            return false;  
        }  
      
        //缓冲区是否为只读  
        public boolean isReadOnly() {  
            return false;  
        }  
          
        //存储字节x到字节缓冲区中,返回字节缓冲区  
        public ByteBuffer put(byte x) {  
            hb[ix(nextPutIndex())] = x;  
            return this;  
        }  
          
        //将指定字节缓冲区的位置的字节更新为x,返回字节缓冲区  
        public ByteBuffer put(int i, byte x) {  
            hb[ix(checkIndex(i))] = x;  
            return this;  
        }  
      
        //将指定的字节数组src的元素存储到当前的字节缓冲区中  
        public ByteBuffer put(byte[] src, int offset, int length) {  
            //检查下标是否越界  
            checkBounds(offset, length, src.length);  
            //检查缓冲区是否溢出  
            if (length > remaining())  
                throw new BufferOverflowException();  
            //将输入的字节数组中src从指定偏移量offset开始复制字节到当前的字节缓冲区  
            System.arraycopy(src, offset, hb, ix(position()), length);  
            //设置当前的字节缓冲区中的读写开始位置为原有的position加上新增的字节数组的length  
            position(position() + length);  
            //返回当前的字节缓冲区  
            return this;  
        }  
      
        //将指定的字节缓冲区的字节存储到当前的字节缓冲区  
        public ByteBuffer put(ByteBuffer src) {  
            //判断src是否为堆字节缓冲区  
            if (src instanceof HeapByteBuffer) {  
                if (src == this)  
                    throw new IllegalArgumentException();  
                //获取堆字节缓冲区  
                HeapByteBuffer sb = (HeapByteBuffer)src;  
                //获取字节缓冲区中剩余字节的容量  
                int n = sb.remaining();  
                if (n > remaining())  
                    throw new BufferOverflowException();  
                //将指定的字节缓冲区的字节复制到当前的字节缓冲区中  
                System.arraycopy(sb.hb, sb.ix(sb.position()),  
                                 hb, ix(position()), n);  
                //设置输入的字节缓冲区src的读写开始位置  
                sb.position(sb.position() + n);  
                //设置当前缓冲区的读写开始位置  
                position(position() + n);  
            } else if (src.isDirect()) {//判断src是否为直接内核缓冲区  
                //获取输入字节缓冲区的字节容量为n  
                int n = src.remaining();  
                if (n > remaining())  
                    throw new BufferOverflowException();  
                //将指定的字节缓冲区src中的字节写入到当前的字节缓冲区hb  
                src.get(hb, ix(position()), n);  
                //设置缓冲区中读写的开始位置为position  
                position(position() + n);  
            } else {  
                //将输入的指定缓冲区中的元素转移到另一个缓冲区中    
                super.put(src);  
            }  
            return this;  
        }  
      
        //压缩当前的字节缓冲区  
        public ByteBuffer compact() {  
            //将当前的缓冲区中的字节数组hb从position+offset开始复制到hb中  
            System.arraycopy(hb, ix(position()), hb, ix(0), remaining());  
            //设置当前的缓冲区中读写的开始位置为字节数组的剩余元素大小  
            position(remaining());  
            //设置读写的最大容量为当前缓冲区的最大容量  
            limit(capacity());  
            //设置标记mark为-1  
            discardMark();  
            return this;  
        }  
      
        //获取指定下标的字节  
        byte _get(int i) {                            
            return hb[i];  
        }  
      
        //将指定下标的字节更新为b  
        void _put(int i, byte b) {                    
            hb[i] = b;  
        }  
    
    

    阅读总结

    (1)HeapByteBuffer堆字节缓冲区是将缓冲区分配在jvm中的heap堆上。


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

    相关文章

      网友评论

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

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