通过测试理解各种方法的用法
test1
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
buffer.flip();
System.out.println("重置游标之后 : " + buffer);
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
重置游标之后 : java.nio.HeapByteBuffer[pos=0 lim=3 cap=8]
0 - 3
1 - 2
2 - 1
概念解释:
position limit capacity
pos - 游标位置, lim - 限制数量, cap - 最大容量
上文出现的方法:
buffer.put(temp); 容易理解
buffer.flip(); 参看下文 flip 是重置游标 : lim = pos (把 pos 赋值给 lim) ; pos = 0; 我理解就是为取值做准备;
buffer.remaining() 参看下文 remaining = lim - pos
buffer.get(i) 容易理解
test2
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
0 - 3
1 - 2
2 - 1
3 - 0
4 - 0
上例子结果验证 remaining = lim - pos 即 8-3=5
[3,2,1,0,0,0,0,0]
for (int i = 0; i < 5; i++)
所以会输出 3,2,1,0,0
test3
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
System.out.println(buffer.get());
结果:
0
分析
[3,2,1,0,0,0,0,0]
↑
此时游标的位置,所以是0
------------------------------------------------------------------------------------------
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
buffer.flip();
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
结果 :
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
0 - 3
1 - 2
2 - 1
分析:
flip: lim = pos,pos=0;
remaining = lim - pos 即 3-0=3
for (int i = 0; i < 3; i++)
[3,2,1,0,0,0,0,0]
↑ ↑ ↑
所以游标取值如上为 3,2,1
------------------------------------------------------------------------------------------
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
System.out.println("-------- ");
buffer.flip();
System.out.println("flip 后 : " + buffer);
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
System.out.println("-------- ");
System.out.println(buffer.get());
System.out.println("get 后 : " + buffer);
System.out.println("-------- ");
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
结果:
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
0 - 3
1 - 2
2 - 1
3 - 0
4 - 0
--------
flip 后 : java.nio.HeapByteBuffer[pos=0 lim=3 cap=8]
0 - 3
1 - 2
2 - 1
--------
3
get 后 : java.nio.HeapByteBuffer[pos=1 lim=3 cap=8]
--------
0 - 3
1 - 2
分析:
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
[0,0,0,0,0,0,0,0]
↑ ●
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
[3,2,1,0,0,0,0,0]
↑ ●
第一个打印:
remaining = 8-3=5
for (int i = 0; i < 5; i++)
所以是 3,2,1,0,0
buffer.flip();
flip 后 : java.nio.HeapByteBuffer[pos=0 lim=3 cap=8]
[3,2,1,0,0,0,0,0]
↑ ●
第二次打印:
remaining = 3-0=3
for (int i = 0; i < 3; i++)
所以是 3,2,1
buffer.get() 取出第一个值,游标自动往后挪一位; 所以结果是3
[3,2,1,0,0,0,0,0]
↑ ●
get 后 : java.nio.HeapByteBuffer[pos=1 lim=3 cap=8]
第三次打印:
remaining = 3-1=2
for (int i = 0; i < 3; i++)
所以结果是 3,2
总结一点就是:flip + remaining 一起使用就是把缓存的内容输出;这个组合是最有意义的
buffer.flip();
for (int i = 0; i < buffer.remaining(); i++) {
int data = buffer.get(i);
System.out.println(i + " - " + data);
}
缓存为 [3,2,1,0,0,0,0,0] 输出结果为:3,2,1
test4
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
buffer.flip();
buffer.flip();
System.out.println(buffer.get());
结果:
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
java.nio.BufferUnderflowException
at java.nio.Buffer.nextGetIndex(Buffer.java:500)
at java.nio.HeapByteBuffer.get(HeapByteBuffer.java:135)
分析:
[3,2,1,0,0,0,0,0]
↑
第一个flip以后: lim = pos,pos=0; lim = 3 , pos = 0;
[3,2,1,0,0,0,0,0]
↑ ●
第二个flip以后: lim = pos,pos=0;lim = 0 , pos = 0;
[3,2,1,0,0,0,0,0]
● ↑
get() -> 获取当前游标指向的位置的数据;此时游标是0指的是第一项,但是此时lim为0表示啥也没有,所以取值会报错
test5
ByteBuffer buffer = ByteBuffer.allocate(8);
byte[] temp = new byte[] {
3, 2, 1};
System.out.println("写入数据之前 : " + buffer);
buffer.put(temp);
System.out.println("写入数据之后 : " + buffer);
buffer.flip();
System.out.println("写入数据之后 : " + buffer);
buffer.clear();
System.out.println("写入数据之后 : " + buffer);
buffer.put((byte) 10);
buffer.put((byte) 11);
System.out.println("写入数据之后 : " + buffer);
------------------------------------------------------------------------------------------
结果:
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=0 lim=3 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
写入数据之后 : java.nio.HeapByteBuffer[pos=2 lim=8 cap=8]
------------------------------------------------------------------------------------------
新方法:
clear(); position = 0; limit = capacity;
------------------------------------------------------------------------------------------
分析:
ByteBuffer.allocate(8);
写入数据之前 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
[0,0,0,0,0,0,0,0]
↑ ●
byte[] temp = new byte[] {
3, 2, 1};
写入数据之后 : java.nio.HeapByteBuffer[pos=3 lim=8 cap=8]
[3,2,1,0,0,0,0,0]
↑ ●
buffer.flip();
写入数据之后 : java.nio.HeapByteBuffer[pos=0 lim=3 cap=8]
[3,2,1,0,0,0,0,0]
↑ ●
buffer.clear();
写入数据之后 : java.nio.HeapByteBuffer[pos=0 lim=8 cap=8]
[3,2,1,0,0,0,0,0]
↑ ●
注意:此时get()还能取到3;再往里添加值回去覆盖原来的值
buffer.put((byte) 10);
[10,2,1,0,0,0,0,0]
↑ ●
buffer.put((byte) 11);
[10,11,1,0,0,0,0,0]
↑ ●
写入数据之后 : java.nio.HeapByteBuffer[pos=2 lim=8 cap=8]
Buffer的应用固定逻辑
写操作顺序
假如原来存储的内容
[10,2,1,0,0,0,0,0]
↑ ●
1. clear()
[10,2,1,0,0,0,0,0]
↑ ●
2. put() -> 写操作 :假设写入1,2,3,4
[1,2,3,4,0,0,0,0]
↑ ●
3. flip() -> 重置游标
[1,2,3,4,0,0,0,0]
↑ ●
4. SocketChannel.write(buffer); -> 将缓存数据发送到网络的另一端
5. clear()
[1,2,3,4,0,0,0,0]
↑ ●
读操作顺序
假如原来存储的内容
[10,2,1,0,0,0,0,0]
↑ ●
1. clear()
[10,2,1,0,0,0,0,0]
↑ ●
2. SocketChannel.read(buffer); -> 从网络中读取数据 假如读进来1,2,3,4
[1,2,3,4,0,0,0,0]
↑ ●
3. buffer.flip() -> 重置游标
[1,2,3,4,0,0,0,0]
↑ ●
4. buffer.get() -> 读取数据
[1,2,3,4,0,0,0,0]
↑ ↑ ↑ ↑ ●
5. buffer.clear()
[1,2,3,4,0,0,0,0]
↑ ●