且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【Java 网络编程】NIO Buffer 简介 ( 概念 | 数据传输 | 标记 | 位置 | 限制 | 容量 | 标记 | 重置 | 清除 | 翻转 | 重绕 | 链式操作 )

更新时间:2022-06-21 04:29:42

文章目录

I. Buffer 简介

II. Buffer 属性

III. Buffer 数据读写

IV. Buffer 标记 mark() 和重置 reset()

V. Buffer 清除 翻转 重绕

VI. Buffer 缓冲区只读属性

VII. Buffer 的链式调用



I. Buffer 简介


Buffer 是在 NIO 中定义的抽象类 , 其针对七种基本数据类型都有对应的实现类 , 如 ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer , IntBuffer , LongBuffer , ShortBuffer ; 其是用于缓存基本数据类型的容器 ;


Buffer 作用 : 在内存中创建指定大小的空间 , 对一些基本类型数据进行缓存 ; 使用缓存能减少读写磁盘的次数 , 这块缓存所占用的内存会一直使用 , 减少了动态内存分配的开销 ;




II. Buffer 属性


Buffer 缓冲区基本属性 :


① 容量 Capacity : 缓冲区元素个数 , 不可更改 ;

② 限制 Limit : 缓冲区的终点 , 从该索引开始 ( 包含该索引 ) , 不能对之后的元素进行读写操作 ; Limit 值可以修改 , 其值必须是自然数 ;

③ 位置 Position : 下一个要被读取或写入的元素索引 , 注意是下一个 , Position 初始值从 0 开始计数 , 如果没有读取就一直是 0 , 如果已经读取了 1 个元素 , 其 Position 值在读取完毕后变为 1 , 指向下一个将要读取的元素 ;

④ 标记 Mark : 调用 mark() 方法可以设置标记 Mark = Position , 之后在任何时刻 , 调用 reset() 方法 , 可以让 Position = Mark ;

四个属性遵循的规律 : M a r k ≤ P o s i t i o n ≤ L i m i t ≤ C a p a c i t y Mark \leq Position \leq Limit \leq CapacityMark≤Position≤Limit≤Capacity




III. Buffer 数据读写


1. Buffer 的 7 个子类 ( ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer , IntBuffer , LongBuffer , ShortBuffer ) , 都定义了两类方法 , 分别是 ① 读取数据 , ② 写入数据 ;



2. 相对操作和绝对操作 :


① 相对操作读写数据 : 缓冲区相对操作读取或写入数据 , 操作完毕后 , Position 被赋值为下一个将要读取或写入的元素索引 , 如果操作的 Position 超出了 Limit , 就会抛出异常 ;

② 绝对操作读写数据 : 直接使用元素索引进行操作 , 该操作不影响 Position 位置属性 ; 如果索引超出了缓冲区大小 , 就会抛出异常 ;



IV. Buffer 标记 mark() 和重置 reset()


标记和重置方法 :


① 操作对象 : 标记 mark() 方法 操作的是 Mark 标记属性 , 重置 reset() 方法 , 主要用于操作 Position 位置属性 ;

② 设置标记 : mark() 方法用于设置标记 , 将当前的 Position 赋值给 Mark 属性 ;

③ 位置重置 : reset() 方法用于重置 Position 位置属性 , 将当前的 Position 位置属性设置成 Mark 标记属性值 ;



V. Buffer 清除 翻转 重绕


1. 清除操作 : 调用 clear() 方法执行 , 执行了该方法后 , 将 Limit 限制属性设置为缓冲区的容量大小 , 将 Position 位置属性设置成 0 , 之后便可以重新从 0 位置开始读写缓冲区 ;


2. 翻转操作 : 调用 flip() 方法执行 , 执行了该方法后 , 将 Limit 限制属性设置为当前 Position 位置属性, 将 Position 位置属性设置成 0 , 之后便可以重新从 0 位置开始读写缓冲区 , 但是不能超过 Limit 位置 ;


3. 重绕操作 : 调用 rewind() 方法执行 , Limit 限制属性保持不变 , 将 Position 位置属性设置成 0 , 只是重新开始写入或读取 ;




VI. Buffer 缓冲区只读属性


Buffer 只读缓冲区 :


① 只读属性 : Buffer 包裹的缓冲区可能是只读的 , 不能向缓冲区中写入数据 ;

② 只读缓冲区操作 : 只读缓冲区的内容是不可以修改的 , 但是缓冲区的 Mark 标记 , Limit 限制 , Position 位置属性是可以改变的 , 缓冲区是只读的 , 不可改变缓冲区及其内容 , 因此 Capacity 容量不可改变 ;

③ 判定是否是只读缓冲区 : 可以调用 isReadOnly() 方法 , 判定该 Buffer 缓冲区是否是制度缓冲区 ;



VII. Buffer 的链式调用


1. 链式调用前提 : Buffer 缓冲区有很多方法的返回值是 Buffer 对象本身 , 如 :


① Buffer clear() 清除缓冲区 ,

② Buffer flip() 翻转缓冲区 ,

③ Buffer limit(int newLimit) 设置缓冲区限制 ,

④ Buffer mark() 设置缓冲区标记 ,

⑤ Buffer position(int newPosition) 设置缓冲区位置 ,

⑥ Buffer reset() 重置缓冲区位置 ,

⑦ Buffer rewind() 缓冲区重绕 ;

2.链式调用示例 :


① 非链式调用 :

ByteBuffer buffer = ByteBuffer.allocate(10) ;
buffer.position(3);
buffer.rewind();
buffer.limit(9);


② 链式调用 :

ByteBuffer buffer = ByteBuffer.allocate(10) ;
buffer.position(3).rewind().limit(9);