
了解二者区别和如何利用
1. java.nio.BufferInvariants
The following invariant holds for the mark, position, limit, and capacity values:
0 <= mark <= position <= limit <= capacity
A newly-created buffer always has a position of zero and a mark that is undefined. The initial limit may be zero, or it may be some other value that depends upon the type of the buffer and the manner in which it is constructed. Each element of a newly-allocated buffer is initialized to zero.
Clearing, flipping, and rewinding
In addition to methods for accessing the position, limit, and capacity values and for marking and resetting, this class also defines the following operations upon buffers:
clear makes a buffer ready for a new sequence of channel-read or relative put operations: It sets the limit to the capacity and the position to zero.
flip makes a buffer ready for a new sequence of channel-write or relative get operations: It sets the limit to the current position and then sets the position to zero.
rewind makes a buffer ready for re-reading the data that it already contains: It leaves the limit unchanged and sets the position to zero.
从文档上可以看出, Buffer的主要参数有
mark,position,limit,capacity
主要的方法有
clear,flip,rewind
具体说明,已知buf的作用是来进行写和读,一般是进行写数据,再进行读数据,
写数据的过程中,每写入一个字节,position + 1, 写入的数量限制到limit
进行读数据的时候,要进行调用filp()方法, 具体是为了将读的(position)位置设置为0(开始), limit设置为(position)最后写入的位置,仅此而已。
实例代码(写入love)
public static void main(String[] args) {
// 创建一个缓冲区
ByteBuffer buffer = ByteBuffer.allocate(10);
System.out.println("------------初始时缓冲区------------");
printBuffer(buffer);
// 添加一些数据到缓冲区中
System.out.println("------------添加数据到缓冲区------------");
String s = "love";
buffer.put(s.getBytes());
printBuffer(buffer);
// 切换成读模式
System.out.println("------------执行flip切换到读取模式------------");
buffer.flip();
printBuffer(buffer);
// 读取数据
System.out.println("------------读取数据------------");
// 创建一个limit()大小的字节数组(因为就只有limit这么多个数据可读)
byte[] bytes = new byte[buffer.limit()];
// 将读取的数据装进我们的字节数组中
buffer.get(bytes);
printBuffer(buffer);
// 执行compact
System.out.println("------------执行compact------------");
buffer.compact();
printBuffer(buffer);
// 执行clear
System.out.println("------------执行clear清空缓冲区------------");
buffer.clear();
printBuffer(buffer);
}
private static void printBuffer(ByteBuffer buffer) {
System.out.println("mark:" + buffer.mark());
System.out.println("position:" + buffer.position());
System.out.println("limit:" + buffer.limit());
System.out.println("capacity:" + buffer.capacity());
}
------------初始时缓冲区------------
mark:java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]
position:0
limit:10
capacity:10
------------添加数据到缓冲区------------
mark:java.nio.HeapByteBuffer[pos=4 lim=10 cap=10]
position:4
limit:10
capacity:10
------------执行flip切换到读取模式------------
mark:java.nio.HeapByteBuffer[pos=0 lim=4 cap=10]
position:0
limit:4
capacity:10
------------读取数据------------
mark:java.nio.HeapByteBuffer[pos=4 lim=4 cap=10]
position:4
limit:4
capacity:10
------------执行compact------------
mark:java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]
position:0
limit:10
capacity:10
------------执行clear清空缓冲区------------
mark:java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]
position:0
limit:10
capacity:10
Process finished with exit code 0
compact和clear的区别是compact方法主要是为了将未读的数据(positoin到limit)拷贝到buf的开头,以便于后面写入的数据从未读的数据后面继续写入 ,防止未读的数据被覆盖,在此过程中,数据进行了一次拷贝。clear主要是进行游标的重置。
2. io.netty.bufferio.netty.buffer相比java.nio.Buffer,前者会后者进行了封装以及更综合的功能,其基本数据和java的基本一致
BEFORE discardReadBytes()
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
AFTER discardReadBytes()
+------------------+--------------------------------------+
| readable bytes | writable bytes (got more space) |
+------------------+--------------------------------------+
| | |
readerIndex (0) <= writerIndex (decreased) <= capacity
示例代码
public static void main(String[] args) {
// 创建一个缓冲区
ByteBuf buffer = Unpooled.buffer(10);
System.out.println("------------初始时缓冲区------------");
printBuffer(buffer);
// 添加一些数据到缓冲区中
System.out.println("------------添加数据到缓冲区------------");
String s = "love";
buffer.writeBytes(s.getBytes());
printBuffer(buffer);
// 读取数据
System.out.println("------------读取数据------------");
while (buffer.isReadable()) {
System.out.println(buffer.readByte());
}
printBuffer(buffer);
// 执行compact
System.out.println("------------执行discardReadBytes------------");
buffer.discardReadBytes();
printBuffer(buffer);
// 执行clear
System.out.println("------------执行clear清空缓冲区------------");
buffer.clear();
printBuffer(buffer);
}
private static void printBuffer(ByteBuf buffer) {
System.out.println("readerIndex:" + buffer.readerIndex());
System.out.println("writerIndex:" + buffer.writerIndex());
System.out.println("capacity:" + buffer.capacity());
}
------------初始时缓冲区------------
readerIndex:0
writerIndex:0
capacity:10
------------添加数据到缓冲区------------
readerIndex:0
writerIndex:4
capacity:10
------------读取数据------------
l
o
v
e
readerIndex:4
writerIndex:4
capacity:10
------------执行discardReadBytes------------
readerIndex:0
writerIndex:0
capacity:10
------------执行clear清空缓冲区------------
readerIndex:0
writerIndex:0
capacity:10
Process finished with exit code 0