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

2023-03-27 17:07:39 浏览数 (2)

文章目录

        • 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 ;

四个属性遵循的规律 :

Mark leq Position leq Limit leq 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.链式调用示例 :

  • ① 非链式调用 :
代码语言:javascript复制
ByteBuffer buffer = ByteBuffer.allocate(10) ;
buffer.position(3);
buffer.rewind();
buffer.limit(9);
  • ② 链式调用 :
代码语言:javascript复制
ByteBuffer buffer = ByteBuffer.allocate(10) ;
buffer.position(3).rewind().limit(9);

0 人点赞