NIO —— 缓冲区Buffer

本文详细介绍了Java NIO中的缓冲区(Buffer)概念及其核心属性:容量(capacity)、界限(limit)、位置(position)和标记(mark)。此外,文章还讲解了如何使用Buffer类及其子类如ByteBuffer和CharBuffer等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缓冲区Buffer

    缓冲区(Buffer
      容量(capacity)、界限(limit)、位置(position)、标签(mark
        Buffer抽象类 API
          putget方法

             

            缓冲区(Buffer

                    从内部结构上来看,Buffer就像一个数组,它可以保存多个类型相同的数据。Buffer是一个抽象类,其最常用的子类是ByteBuffer,它可以在底层字节数组上进行get/set操作。除了ByteBuffer之外,对应于其他基本数据类型(boolean除外)都有相应的Buffer类:CharBufferShortBufferIntBufferLongBufferFloatBufferDoubleBuffer

                    上面这些Buffer类,除了ByteBuffer之外,它们都采用相同或相似的方法来管理数据,只是各自管理的数据类型不同而已。这些Buffer类都没有提供构造器,通过使用如下方法来得到一个Buffer对象。

              static XxxBuffer allocate(int capacity):创建一个容量为capacityXxxBuffer对象。

                       但实际使用较多的是ByteBufferCharBuffer,其他Buffer子类则较少用到。其中ByteBuffer类还有一个子类:MappedByteBuffer,它用于表示Channel将磁盘文件的部分或全部内容映射到内存中后得到的结果,通常MappedByteBuffer对象由Channelmap()方法返回。

                 

                容量(capacity)、界限(limit)、位置(position)、标签(mark

                容量(capacity

                   缓冲区的容量(capacity)表示该Buffer的最大数据容量,即最多可以存储多少数据。缓冲区的容量不可能为负值,创建后不能改变。

                界限(limit

                   第一个不应该被读写或者写入的缓冲区位置索引。也就是说,位于limit后的数据既不可被读,也不可被写。

                位置(position

                   用于指明下一个可以被读出或者写入的缓冲区位置索引(类似于IO流中的记录指针)。当使用BufferChannel中读取数据时,position的值恰好等于已经读到了多少数据。当刚刚新建一个Buffer对象时,其position0;如果从Channel中读取了2个数据到该Buffer中,则position2,指向Buffer中的第三个(第1个位置的索引为0)位置。

                标记(mark

                   Buffer里还支持一个可选的标记(mark,类似于传统IO流中的mark),Buffer允许直接将position定位到该mark处。

                   一个备忘位置。调用 mark()来设定 mark = postion。调用 reset()设定 position =mark。标记在设定前是未定义的( undefined)

                关系

                0 <= mark <= position <= limit <= capacity


                 

                Buffer抽象类常用方法

                int capacity();

                   返回Buffercapacity大小。

                boolean hasRemaining();

                   判断当前位置(position)和界限(limit)之间是否有元素可供处理。

                int limit();

                   返回Buffer的界限(limit)的位置。

                Buffer limit(int newLimit);

                   重新设置界限(limit)的值,并返回一个具有新的limit的缓冲区对象。

                int position();

                   返回Bufferposition值。

                Buffer position(new position);

                   设置Bufferposition值,并返回position被修改后的Buffer对象。

                int remaining();

                   返回当前位置和界限(limit)之间的元素个数。

                Buffer reset();

                   将位置(position)转到mark所在的位置。

                Buffer rewind();

                   将位置(position)设置为0,取消设置的mark

                 

                putget方法

                   Buffer API 并没有包括 get()或 put()函数,因为每一个 Buffer 类都有这两个函数,但它们所采用的参数类型,以及它们返回的数据类型,对每个子类来说都是唯一的,所以它们不能在顶层 Buffer 类中被抽象地声明。下面以ByteBuffer为例:

                publicabstractclass ByteBufferextends Bufferimplements Comparable{

                //     This is a partial API listing

                publicabstractbyte get( );

                publicabstractbyte get (int index);

                publicabstract ByteBuffer put (byte b);

                publicabstract ByteBuffer put (int index,byte b);

                }

                相对(Relative)与绝对(Absolute):

                   get put可以是相对的或者是绝对的。在前面的程序列表中,相对方案是不带有索引参数的函数。当相对函数被调用时,位置在返回时前进一。如果位置前进过多,相对运算就会抛 出 异 常 。 对 于 put() , 如 果 运 算 会 导 致 位 置 超 出 上 界 , 就 会 抛 出BufferOverflowException 异常。对于 get(),如果位置不小于上界,就会抛出BufferUnderflowException 异常。绝对存取不会影响缓冲区的位置属性,但是如果您所提供的索引超出范围(负数或不小于上界),也将抛出 IndexOutOfBoundsException 异常。

                 

                 

                已使用 广州传智播客 创建。

                评论
                添加红包

                请填写红包祝福语或标题

                红包个数最小为10个

                红包金额最低5元

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

                抵扣说明:

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

                余额充值