1.随机访问索引

/**
* Listing 5.6 Access data
*/
@Test
public void byteBufRelativeAccess() {
//创建一个16字节的buffer,这里默认是创建heap buffer
ByteBuf buf = Unpooled.buffer(16);
//写数据到buffer
for(int i=0; i<buf.capacity(); i++){
buf.writeByte(i+1);
}
//读数据
for(int i=0; i<buf.capacity(); i++){
System.out.print(buf.getByte(i)+", ");
}
}
2.可丢弃字节


@Test
public void readAllDataTest() {
ByteBuf buf = Unpooled.buffer(16); //get reference form somewhere
//写数据到buffer
for(int i=0; i<buf.capacity(); i++){
buf.writeByte(i+1);
}
for(int i=0; i<buf.capacity()-1; i++){
System.out.println(buf.readByte());
}
buf.discardReadBytes();
while (buf.isReadable()) {
System.out.println(buf.readByte());
//buf.discardReadBytes();
}
}
在调用discardReadBytes之前的readerIndex和writerIndex信息

在调用discardReadBytes之后,readerIndex和writerIndex都发生了变化,包括array数组,array数组的数据也会向左偏移,否则readerIndex发生变化就会出错


3.可读字节
@Test
public void readAllData() {
ByteBuf buffer = Unpooled.buffer(16); //get reference form somewhere
//写数据到buffer
for(int i=0; i<buffer.capacity(); i++){
buffer.writeByte(i+1);
}
while (buffer.isReadable()) {
System.out.println(buffer.readByte());
}
}

4.可写字节

@Test
public void write() {
// Fills the writable bytes of a buffer with random integers.
ByteBuf buffer = Unpooled.buffer(16); //get reference form somewhere
while (buffer.writableBytes() >= 4) {
buffer.writeInt(random.nextInt());
}
}
5.索引管理

5.1 markIndex
@Test
public void markIndex() {
ByteBuf buffer = Unpooled.buffer(16); //get reference form somewhere
//写数据到buffer
for(int i=0; i<5; i++){
buffer.writeByte(i+1);
}
System.out.println(buffer.writerIndex());
buffer.markWriterIndex();
buffer.writeByte(1);
System.out.println(buffer.writerIndex());
buffer.resetWriterIndex();
System.out.println(buffer.writerIndex());
buffer.writeByte(2);
buffer.markReaderIndex();
System.out.println(buffer.readByte());
buffer.resetReaderIndex();
System.out.println(buffer.readByte());
}
输出:
5
6
5
1
1
5.2 writerIndex和readerIndex直接设置
@Test
public void setIndex() {
ByteBuf buffer = Unpooled.buffer(16); //get reference form somewhere
//写数据到buffer
for(int i=0; i<5; i++){
buffer.writeByte(i+1);
}
buffer.writerIndex(2);
System.out.println(buffer.writerIndex());
buffer.readerIndex(1);
System.out.println(buffer.readerIndex());
}
5.3 clear
调用 clear()比调用 discardReadBytes()轻量得多, 因为它将只是重置索引而不会复
制任何的内存。
public ByteBuf clear() {
readerIndex = writerIndex = 0;
return this;
}
6. 派生缓冲区
@Test
public void byteBufOp() {
Charset utf8 = Charset.forName("UTF-8");
// 创建一个用于保存给定字符串的字节的ByteBuf
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
ByteBuf duplicate = buf.duplicate();
ByteBuf sliced = buf.slice(0, 15);
ByteBuf readSlice=buf.readSlice(10);
// 将打印“Netty in Action”
System.out.println(sliced.toString(utf8));
// 更新索引0 处的字节
buf.setByte(0, (byte) 'J');
// 将会成功,因为数据是共享的,对其中一个所做的更改对另外一个也是可见的
assert buf.getByte(0) == sliced.getByte(0);
}
派生的场景化ByteBuf,其内部是共享内存的,并不会真实的拷贝

7. 真实拷贝
可以调用copy方法来进行拷贝副本,该方法不会共享内存
public static void byteBufCopy() {
Charset utf8 = Charset.forName("UTF-8");
// 创建一个用于保存给定字符串的字节的ByteBuf
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
// 创建该ByteBuf 从索引0 开始到索引15结束的分段的副本
ByteBuf copy = buf.copy(0, 15);
// 将打印“Netty in Action”
System.out.println(copy.toString(utf8));
// 更新索引0 处的字节
buf.setByte(0, (byte) 'J');
// 将会成功,因为数据不是共享的
assert buf.getByte(0) != copy.getByte(0);
}
网友评论