Buffer是个啥?

Buffer 即缓冲区,用来暂存输入输出数据的区域。Buffer对象是一份固定数量的数据的容器,实质上是一个数组。但是一个缓冲区不仅仅是一个数组,缓冲区提供了对数据的结构化访问,还可以跟踪系统的读/写进程。
 
在 Java传统 IO 中,数据直接写入或者将数据直接读到 Stream 对象中。
而在 NIO 中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,都是将它放到缓冲区中。
NIO中的Buffer主要用于与NIO通道(channel)进行交互,数据是从通道读入缓冲区,从缓冲区写入通道中的。
 

继承关系图

Buffer作为一个容器用来存储数据的,根据存储数据类型的不同,分为以下七种:
ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer

主要属性

// 标记、位置、限制、容量遵守以下不变式:
// 0<=mark<=position<=limit<=capacity // 标记是一个位置索引,可以在之后设置位置为标记值再次读写。
private int mark = -1; // 位置,表示缓冲区中正在操作数据的位置。
// 可以把position理解成一个指针,指向的位置就是操作的位置。
private int position = 0; // 界限,表示缓冲区中可以操作数据的大小。
private int limit; // 容量,表示缓冲区中最大存储数据的容量。一旦声明,不可改变。
private int capacity; // 指向缓冲区的地址
long address;

构造方法

// 创建一个具有给定标记、位置、限制和容量的新缓冲区
Buffer(int mark, int pos, int lim, int cap) {
// 缓冲区的初始化容量不能小于0
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
// 初始化缓冲区容量
this.capacity = cap;
// 初始化缓冲区限制,设置最新的缓冲区Buffer
limit(lim);
position(pos);
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("
+ mark + " > " + pos + ")");
this.mark = mark;
}
}

关键方法解析

position方法:设置当前操作位置

public final Buffer position(int newPosition) {
// 当前操作位置不能超过limit大小,不能小于0
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
// 如果标记位置大于正在操作位置,那么将mark设置为-1。
if (mark > position) mark = -1;
return this;
}

limit方法:设置缓冲区限制

public final Buffer limit(int newLimit) {
// newLimit大小不能超过缓冲区最大容量capacity,不能小于0
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
limit = newLimit;
// 正在操作数据的位置不能大于界限
if (position > limit) position = limit;
// 如果标记位置大于界限,那么将mark设置为-1。
if (mark > limit) mark = -1;
return this;
}

reset方法:将缓冲区Buffer的位置position设置为以前临时备忘变量mark存储的位置

public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
clear方法:清除缓冲区,clear方法并没有将之前的数据真的清除,当读数据前调用flip方法后,limit会限制不让使用旧数据。
public final Buffer clear() {
position = 0;
// 虽然将limit数值设置为最大容量,只是为了正常使用buffer
limit = capacity;
mark = -1;
return this;
}

flip方法: 反转此缓冲区,在进行写完去读的时候使用,说白了,让你开始读的时候从初始位置0开始。

public final Buffer flip() {
// 将position置为0,其实就是切换读写模式
limit = position;
position = 0;
mark = -1;
return this;
}

rewind方法:重绕此缓冲区,在通道写入或者获取之前调用

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

remaining方法:返回当前的缓冲区Buffer中剩余元素的数量

public final int remaining() {
return limit - position;
}

总结

1、Buffer中所有的方法操作,都遵守以下不变式:
 0<=mark<=position<=limit<=capacity
2、flip方法,让数据开始读的时候从初始位置0开始。
3、clear方法其实是个障眼法,并没有清除之前数据内容。

最新文章

  1. iOS学习19之OC类的扩展
  2. com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 2-byte
  3. python语法笔记(三)
  4. setcookie 之 我见
  5. Struts2中的session、request、respsonse获取方法
  6. 使用Idea编写javaweb以及maven的综合(一)
  7. 一套代码小程序&amp;Web&amp;Native运行的探索05——snabbdom
  8. Chrome 禁止从页面打开 Data URI 网址了
  9. Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
  10. 47_并发编程-线程python实现
  11. JavaEE编程实验 实验1 Java常用工具类编程(未完成)
  12. Exception的妙用
  13. 【转】Visual Studio团队资源管理器 Git 源码管理工具简单入门
  14. JAVA序列化和反序列化 对象&lt;=&gt;IO流 对象&lt;=&gt;字节数组
  15. ubuntu查找命令比较
  16. 解释mysql 语句 ——解释CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
  17. PAT 1001 Format
  18. thinkphp5中Indirect modification of overloaded element of XXX has no effect的解决办法
  19. Spring Data JPA 基本使用
  20. rails 中 create, new, build, save 的用法以及误区汇总 (转)

热门文章

  1. struct模块(用于对象的压缩)
  2. C#3.0新增功能09 LINQ 标准查询运算符 01 概述
  3. [leetcode] 135. Candy (hard)
  4. Netty中的装饰者模式
  5. 15款好用超赞的chrome插件, 开发者们的必备~
  6. 【JS档案揭秘】第一集 内存泄漏与垃圾回收
  7. 【iOS】创建真机调试证书
  8. http协议(一):http协议基础知识
  9. Flutter学习笔记(13)--表单组件
  10. RocketMQ中NameServer的启动