NIO三件套☞Buffer缓冲区

本文深入探讨了NIO中的缓冲区概念,详细解释了ByteBuffer和其他基本类型缓冲区的作用,以及mark、position、limit和capacity等关键属性的工作原理。通过代码示例展示了这些属性在读写操作中的变化。

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

Buffer 缓冲区

缓冲区其实就是一个容器对象,在NIO 中,所有的数据用缓冲区处理的。在读取数据时,它是直接读取到缓冲区中的,写数据也是直接入到缓冲区。

在NIO 中,每一种基本类型都具有一个对应的缓冲区,最常见的就是ByteBuffer。

在这里插入图片描述

通过上面的图可以看出来,每个缓冲区都存在hb 的一个不同类型的数组,这个就是用来存储数据, 在他的父类Buffer 有 mark ,position limit capacity 4个属性值。

​ 这四个的值大小 mark <= position <= limit <= capacity,如果有出现不符合这个的就会抛出异常。

  • mark : 表示一个临时存放的下标值(只有调用,mark() 方法时 才会使得 position 的值个mark, 初始值 为 -1)
  • position: 指定下一个将要被写入或者读取的元素的位置,它是在get()/put()方法中自动更新的,position 的初始值为0。
  • limit : 指定还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据。
  • capacity: 指定最大的容量。实际上它是指定数组的大小。
package neety.nio.buffer;

import java.nio.IntBuffer;

public class IntBufferDemo {

    public static void main(String[] args) {
        /* 分配新的int 缓冲区,参数为缓存区的容量
        *  新缓冲区的当前位置为0,其界限(限制位置) 为其容量,他具有一个底层实现数组,其数组偏移量为0
        *    private int mark = -1;
             private int position = 0;
             private int limit; // 偏移量
             private int capacity; // 容器量
        *   final int[] hb;                  // Non-null only for heap buffers
        * */
        IntBuffer buffer = IntBuffer.allocate(8);

        for (int i = 0 ; i < buffer.capacity() ; ++i){
            int j = 2 * (i +1);
            buffer.put(j);
        }
        // 重新设置该缓冲区,见限制位置(position)设置到当前位置 position ++
        buffer.flip();
        // 查看当前位置和限制位置之间是否存在元素。
        while (buffer.hasRemaining()) {
            buffer.mark();
            int j = buffer.get();
            System.out.println(j+" ");
        }

    }
}

可以通过下面这个代码仔细的观察 position limit capacity 的三值的变化。 capacity 一般是不变的就是最大容量。主要是观察 position 和limit 的变化

package neety.nio.buffer;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class BufferDemo {

    public static void main(String[] args) throws IOException {
        //这里用文件I/O处理
        FileInputStream fileInputStream = new FileInputStream("H:\\workspace\\Java\\IDEAspaceWork\\Study\\src\\main\\java\\neety\\test.txt");
        //创建文件通道
      FileChannel fileChannel = fileInputStream.getChannel();

      // 分配一个10 大小的缓冲区
        ByteBuffer byteBuf = ByteBuffer.allocate(10);

        out("初始化",byteBuf);
        // 读取buffer
        fileChannel.read(byteBuf);
        out("读取文件写入通道",byteBuf);
        //锁定 limit = position 范围
        byteBuf.flip();
        out("锁定limit",byteBuf);

        // 查看当前位置和限制位置之间是否存在元素。
        while (byteBuf.hasRemaining()) {
            byte j = byteBuf.get();
            System.out.print(((char)j)+" ");
        }
         System.out.println();
        out("获取通道数据后的变化:get()",byteBuf);
         byteBuf.clear();

        out("clear()",byteBuf);
        //关闭通道
        fileChannel.close();
    }

    private static void out(String step, ByteBuffer byteBuf) {
        System.out.println(step +": ");
        // 容量大小
        System.out.println("capacity :"+byteBuf.capacity());
        // 读取的位置
        System.out.println("position :"+byteBuf.position());
        // 锁定值 limit ,   postion 到 capacity 的范围
        System.out.println("limit :" + byteBuf.limit());
        System.out.println();
    }

}

初始化: 
capacity :10  //调用了初始的最大容器是10
position :0
limit :10 // 可以扩张的存入的值也是10 

读取文件写入通道:  
capacity :10 
position :4  // 读取文件过后写入到通道里面区 里面就存在文件中的四个字符
limit :10 

锁定limit: 
capacity :10
position :0 // 这个时候掉了filp(); 方法就是 position 赋值给limit 
limit :4
 /**
     public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }
  */
test 
    
获取通道数据后的变化:get(): 
capacity :10
position :4
limit :4
    
/**调用git 方法主要是 对于position的值做++
	* final int nextGetIndex() {                          // package-private
        if (position >= limit)
            throw new BufferUnderflowException();
        return position++;
    }

	**/
clear(): 
capacity :10
position :0
limit :10
/** 将capacity 值赋值给limit 
*  
  public final Buffer clear() {
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }
**/

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值