NIO缓冲区(Buffer)的数据存储

缓冲区

缓冲区(Buffer)在Java NIO中负责数据的存储。缓冲区就是数组。用于存储不同数据类型的数组。

根据数据类型不同(boolean类型除外),提供了对应类型的缓冲区。

ByteBuffer(常用)、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer

上述缓冲区管理方式几乎一致,都是通过allocate()获取缓冲区。



缓冲区存取数据的两个核心方法

put() :存入数据到缓冲区中

get() :获取缓冲区中的数据



缓冲区中的四个核心属性

capacity:容量,表示缓冲区中最大存储容量,一旦声明,不能改变。

limit:界限,表示缓冲区中可以操作数据的大小。(limit后面的数据不能进行读写)

position:位置,表示缓冲区中正在操作数据的位置。position<=limit<=capacity

mark:标记,表示记录当前position的位置,可以通过reset()恢复到刚才mark的位置



缓冲区读取数据

1.分配一个指定大小的缓冲区

1、最大容量为1024

2、界限为1024

3、位置为0

1
2
3
4
5
ByteBuffer buffer=ByteBuffer.allocate(1024);
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");

2.利用put方法存入数据到缓冲区中去

1、最大容量为1024

2、界限为1024

3、位置为5

1
2
3
4
5
buffer.put("abcde".getBytes());
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");

3.通过flip方法切换到读数据模式

1、最大容量为1024

2、界限为5

3、位置为0

1
2
3
4
5
buffer.flip();
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");

4.利用get方法读取缓冲区中的数据

1、最大容量为1024

2、界限为5

3、位置为5

1
2
3
4
5
6
7
byte [] by=new byte[buffer.limit()];
buffer.get(by);
syso(new String(by,0,by.length));
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");

5.利用rewind重复读数据

1、最大容量为1024

2、界限为5

3、位置为0

1
2
3
4
5
buffer.rewind();
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");

6.清空缓冲区,缓冲区中数据还在,数据处于被遗忘状态

1、最大容量为1024

2、界限为1024

3、位置为0

1
2
3
4
5
buffer.clear();
syso(buffer.position());
syso(buffer.limit());
syso(buffer.capacity());
syso("-------------------------");



缓冲区mark(标记)的使用

mark()方法用于标记当前position位置

reset()方法将position恢复到标记的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

String string="abcde";
ByteBuffer buffer=ByteBuffer.allocate(1024);
buffer.put(string.getBytes());
//切换到读取模式
buffer.flip();
byte [] by=new byte[buffer.limit()];
buffer.get(by,0,2);
syso(buffer.position());//结果2
//mark 标记
buffer.mark();
buffer.get(by,2,2);
syso(buffer.position());//结果4
//通过reset恢复到mark位置
buffer.reset();
syso(buffer.position());//结果2



Buffer的slice方法

通过slice方法创建的sliceBuffer它们共同的数据只有一份,通过原有Buffer或sliceBuffer的修改会反映在另外一个Buffer上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ByteBuffer byteBuffer=ByteBuffer.allocate(10);
//放入数据到byteBuffer
for(int i = 0; i< byteBuffer.capacity(); ++i){
byteBuffer.put((byte)i);
}
byteBuffer.position(2);
byteBuffer.limit(6);
//创建sliceBuffer,修改sliceBuffer上的值为原来的2倍
ByteBuffer sliceBuffer=byteBuffer.slice();
for(int i=0;i<sliceBuffer.capacity();++i){
byte b = sliceBuffer.get(i);
sliceBuffer.put(i, (byte) (2*b));
}
byteBuffer.position(0);
byteBuffer.limit(byteBuffer.capacity());
//查看byteBuffer上的值的变化
while(byteBuffer.hasRemaining()){
System.out.println(byteBuffer.get());
}

程序运行结果

img



只读Buffer

我们可以随时将一个普通Buffer调用asReadOnlyBuffer方法返回一个只读Buffer,但不能将只读Buffer转换为一个读写Buffer

1
2
3
4
5
ByteBuffer byteBuffer=ByteBuffer.allocate(10);
for(int i=0;i<byteBuffer.capacity();++i){
byteBuffer.put((byte)i);
}
ByteBuffer readonlyBuffer=byteBuffer.asReadOnlyBuffer();



直接缓冲区和非直接缓冲区

非直接缓冲区:通过allocate() 方法分配缓冲区,将缓冲区建立在JVM的内存中。

直接缓冲区:通过allocateDirect() 方法分配直接缓冲区,将缓冲区建立在操作系统的物理内存中,可以提高效率。

非直接缓冲区

img

直接缓冲区

img

原文:大专栏  NIO缓冲区(Buffer)的数据存储


猜你喜欢

转载自www.cnblogs.com/wangziqiang123/p/11642079.html
今日推荐