一.缓冲区
2.1 缓冲区
1.概念
- 缓冲区以及缓冲区如何工作,是所有IO的基础。
-
所谓输入/输出,无非是把数据移进或移出缓冲区。
2.缓冲区的操作简图
说明:
- 用户空间和内核空间
1).用户空间是常规进程所在区域,JVM就是常规进程,驻于用户空间;
2).内核空间与设备通讯,控制着用户区域进程的运行状态;所有的IO 都直接或间接通过内核空间; - 读操作说明
1).进程发起read 请求;
2).内核接收到read 请求后,先检查内核空间;已经存在,则直接把数据copy给进程的缓冲区;
3).如果没有,则向磁盘控制器发出命令以读取磁盘数据
4).磁盘控制器把数据直接写入内核read 缓冲区(通过DMA 完成)
5).内核将数据copy 到进程缓冲区 - 写操作说明
1).用户缓冲区数据 -> 内核缓冲区 -> 磁盘
二.基础
2.1 缓冲区
1.缓冲区是基本的数据元素组。
2.Buffer 类和简单数组相比,包含数据的数据内容和信息,并有专门的API 和子类。
3.属性
- 容量(Capacity)
1).缓冲区能容纳的数据元素的最大数量
2).创建缓冲区时设定,永远不能改变 - 上界(Limit)
1).缓冲区中现存元素的计数
2).是缓冲区中第一个不能读或者写的元素 - 位置(Position)
1).下一个被读或者被写的元素的索引
2).位置自动的由get() 和 put() 函数更新 - 标记(Mark)
2.2 使用
1.翻转(flip)
- flip() 能将一个能够继续添加数据元素的填充状态的缓冲区翻转成一个准备读出元素的释放状态。
1.3 创建缓冲区
1.新的缓冲区是由分配或包装操作创建的。
- 分配操作创建一个缓冲区对象并分配一个私有的空间来储存容量大小的数据元素。
- 包装操作创建一个缓冲区对象但是不分配任何空间来储存数据元素。
它使用您所提供的数组作为存储空间来储存缓冲区中的数据元素。
2. 分配举例
CharBuffer charBuffer = CharBuffer.allocate (100);
说明:隐含从堆空间中分配了一个char 数组作为备份存储器来存储100 个char 变量。
3.包装举例
char [] myArray = new char [100];
CharBuffer charbuffer = CharBuffer.wrap (myArray);
这段代码构造了一个新的缓冲区对象,但数据元素会存在于数组中。
这意味着通过调用put()函数造成的对缓冲区的改动会直接影响这个数组,而且对这个数组的任何改动也会对这个缓冲区对象可见。
CharBuffer charbuffer = CharBuffer.wrap (myArray, 12, 42);
带有offset和length作为参数的wrap()函数版本则会构造一个按照您提供的offset和length参数值初始化位置和上界的缓冲区。
- 这个函数并不像您可能认为的那样,创建了一个只占用了一个数组子集的缓冲区。
- 这个缓冲区可以存取这个数组的全部范围;offset和length参数只是设置了初始的状态。