NIO - Buffer缓冲区

本文深入解析 Java 缓冲区 (Buffer) 类的实现原理与使用方法,包括其关键属性与方法,并通过文件读取实例展示实际应用。

*Buffer: 缓冲区 是特定基本类型元素的线性有限序列

Buffer中的数据结构是原始数据类型的数组

例如 jdk ByteBuffer中定义的byrte数组

public abstract class ByteBuffer  extends Buffer
    implements Comparable<ByteBuffer>
{
    final byte[] hb;
}

Buffer类图(除去boolean原始类型没有 其他都有)


*Buffer的实例化

1.Buffer具体子类的allocate方法

例如 ByteBuffer

public static ByteBuffer allocate(int capacity){}  //参数为Buffer的容量

2.Buffer具体子类的wrapa方法

例如DoubleBuffer

public static DoubleBuffer wrap(double[] array) {}


*重要属性(父类Buffer中定义):

1.capacity 容量 缓冲区中能够容纳元素的数量 也就是Buffer中数组的大小 不可以改变

2.position 位置 下一个要操作(读写)的元素索引 位置会随着调用相应的read put等方法改变

3.limit 上限 缓冲区中目前容纳了 多少元素 也就是缓冲区中目前元素的个数

4.mark 用于记录position的当前位置 在调用reset方法重新设置position的值为 mark变量上次记录的

上面四个属性 要遵循一下关系

0 <= 标记(mark) <= 位置(position) <= 限制 (limit)<= 容量(capacity)

*重要方法(以ByteBuffer为例)

1. 获取缓冲区中的内容 此方法有多个版本重载

    public byte get() {
	return hb[ix(nextGetIndex())];
    }

2.向缓冲区写入数据 有多个重载

   public ByteBuffer put(byte x) {
	hb[ix(nextPutIndex())] = x;
	return this;
    }

3.在当前缓冲区基础上 创建一个新的缓冲区

    public ByteBuffer slice() {
	return new HeapByteBuffer(hb, -1, 0,this.remaining(),this.remaining(), this.position() + offset);
    }

4 返回缓冲区的容量

    public final int capacity() {
	return capacity;
    }

5. 为position做个标记

    public final Buffer mark() {
	mark = position;
	return this;
    }

6.将缓冲区的位置设置为以前标记的位置

    public final Buffer reset() {
        int m = mark;
	position = m;
	return this;
    }

7.返回缓冲区下一个要操作元素的索引

    public final int position() {
	return position;
    }

8.设置缓冲区起始操作(读写)索引 和 有效数据索引

    public final Buffer flip() {
	limit = position;
	position = 0;
	mark = -1;
	return this;
    }

9.重置缓冲区

    public final Buffer clear() {
	position = 0;
	limit = capacity;
	mark = -1;
	return this;
    }

后面两个方法很重要

读文件的实例代码

//..省略
		FileChannel fileChannel = fileInputStream.getChannel();
		//1.初始化内部数组
		ByteBuffer buffer = ByteBuffer.allocate(4);
		//2.read方法会设置position
		while(fileChannel.read(buffer) != -1) {
			//3.limit = position; 
			//position = 0
			buffer.flip();
			System.out.println(charset.decode(buffer));
			//4.position = 0, limit=capacity
			buffer.clear();	
		}
		//..省略

1.初始化容量为 4的Buffer Buffer 数组全部是空的

2.调用Channel的read方法 向缓冲区写入2个字节

3.如果这个时候调用 Buffer get方法 读的是position =2 limit=3之间的数据


4.调用 Buffer #flip方法之后

5.再一次调用Buffer get方法

6.Buffer clean方法

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值