介绍
- Netty的ByteBuf数据位置索引是从0开始的,类似于数组。
- getByte(int index):从指定位置读出一字节,这个操作不会改变ByteBuf的readerIndex或者 writerIndex 的位置。这个操作也不受readerIndex的影响(例如,当前readerIndex是1,但照样可以用getByte(0)从位置0处得到数据)。如果index小于0,或者index + 1大于ByteBuf的容量,就会抛出IndexOutOfBoundsException异常。
- readByte():从当前readerIndex 读出一字节,并且将readerIndex的值增加1。如果ByteBuf的readableBytes的值小于1,就会抛出IndexOutOfBoundsException异常。
- readBytes(byte[] dst):从当前readerIndex 读出dst.length个字节到字节数组dst中,并将buffer的readerIndex增加dst.length。操作完成后,buffer和数组dst的内容修改互不影响。
- isReadable():方法判断是否有可读的数据。当(this.writerIndex -this.readerIndex) 的值大于0,isReadable()返回true。
- writeShort(int value):在ByteBuf的当前writerIndex位置开始写入一个16位的整数,并且将writerIndex增加2。因为输入参数是int型,占4个字节,高位的16位被丢弃。
- getShort(int index):从ByteBuf的绝对位置index开始,读取1个16位的整数。这个方法不改变ByteBuf的readerIndex和writerIndex。
- getBytes(int index, byte[] dst):从ByteBuf的位置index开始,拷贝部分字节的内容到数组dst中,拷贝的字节数等于dst数组的长度。拷贝以后,再修改本buffer或者数组dst的内容互不影响。
代码举例
用getByte(int index)方法正常读取数据
代码:
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(1);
for (int i = 0; i < 1; i++) {
buf.writeByte(0x68);
}
for (int i = 0; i < buf.capacity(); i++) {
System.out.println(buf.getByte(i));
}
}
}
运行输出:
用getByte(int index)方法不正常读取数,据抛出异常
代码:
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(1);
for (int i = 0; i < 1; i++) {
buf.writeByte(0x68);
}
for (int i = 0; i < buf.capacity() + 1; i++) {
System.out.println(buf.getByte(i));
}
}
}
运行输出:
用getByte(int index)获取数据不受buffer的readerIndex的影响
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Demo {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer();
buf.writeByte(104);
buf.writeByte(22);
buf.readByte();
System.out.println("buf.readerIndex: " + buf.readerIndex());
// 尽管当前readerIndex是1,但照样可以从位置0处获得数据
System.out.println("buf.getByte(0): " + buf.getByte(0));
}
}
运行输出:
buf.readerIndex: 1
buf.getByte(0): 104
用readByte()方法正常读取数据–用readableBytes()判断可读的数据字节数
代码:
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(2);
for (int i = 0; i < 2; i++) {
buf.writeByte(0x68);
}
while (buf.readableBytes() > 0) {
System.out.println(buf.readByte());
}
}
}
运行输出:
用readBytes(int length)方法读取一定数量的字节到一个新创建的ByteBuf中
readBytes(int length)方法是从当前的ByteBuf的readerIndex开始,读取length字节的数据到一个新创建的ByteBuf中,并将readerIndex增加length。
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer();
// 往buf中写入10个字节的数据
for (int i =0; i < 10; i++) {
buf.writeByte(0x68);
}
// 从buf中读取所有可读的数据到新创建的ByteBuf中
ByteBuf dst = buf.readBytes(buf.readableBytes());
System.out.println("dst.readableBytes(): " + dst.readableBytes());
System.out.println("dst.capacity(): " + dst.capacity());
}
}
运行输出:
dst.readableBytes(): 10
dst.capacity(): 10
用readBytes(byte[] dst) 读出部分数据到字节数组中,操作完成后,buffer和数组的内容修改互不影响
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Demo {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer();
buf.writeByte(104);
buf.writeByte(22);
byte[] dst = new byte[2];
buf.readBytes(dst);
System.out.println("before byte array change, dst[0] = " + dst[0]);
System.out.println("before byte array change, buf.getByte(0): " + buf.getByte(0));
dst[0] = (byte)33;
dst[1] = (byte)33;
System.out.println("after byte array change, dst[0] = " + dst[0]);
System.out.println("after byte array change, buf.getByte(0): " + buf.getByte(0));
}
}
运行输出:
before byte array change, dst[0] = 104
before byte array change, buf.getByte(0): 104
after byte array change, dst[0] = 33
after byte array change, buf.getByte(0): 104
用readByte()方法正常读取数据–用isReadable()判断是否有可读的数据
isReadable():当ByteBuf的(writerIndex - readerIndex) > 0返回true。
代码:
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(2);
for (int i = 0; i < 2; i++) {
buf.writeByte(0x68);
}
while (buf.isReadable()) {
System.out.println(buf.readByte());
}
}
}
运行输出:
用isReadable(int size)判断是否有size个字节可读
isReadable(int size):如果ByteBuf中有size个字节可读,结果返回true。
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer();
// 往buf中写入5个字节的数据
for (int i =0; i < 5; i++) {
buf.writeByte(0x68);
}
// 判断buf是否有5个字节可读,结果为true
System.out.println(buf.isReadable(5));
// 读出1个字节,readerIndex加1,还剩4个可读字节
buf.readByte();
// 再次判断buf是否有5个字节可读,结果为false
System.out.println(buf.isReadable(5));
}
}
运行输出:
true
false
用getBytes(int index, byte[] dst)读取部分内容到数组中
getBytes(int index, byte[] dst)表示从ByteBuf的绝对位置index开始,拷贝部分内容到目的字节数组中。这个操作不改变ByteBuf的readerIndex 和 writerIndex。
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(4);
for (int i = 0; i < buf.capacity(); i++) {
buf.writeByte(0x68);
}
byte[] data = new byte[2];
// 从buf的第二个字节开始,拷贝2个字节的内容到data数组中
buf.getBytes(1, data);
System.out.println("数组data的内容:");
for (int i = 0; i < data.length; i++) {
System.out.println(data[i]);
}
System.out.println("buf的内容:");
for (int i = 0; i < buf.capacity(); i++) {
System.out.println(buf.getByte(i));
}
}
}
运行结果:
用getBytes(int index, byte[] dst)读取部分内容到数组中,拷贝完后后,修改本buffer或者数组的内容互不影响
拷贝完后后,修改本buffer或者数组的内容互不影响。
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Demo {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(4);
for (int i = 0; i < buf.capacity(); i++) {
buf.writeByte(i + 10);
}
byte[] data = new byte[2];
// 从buf的第1个字节开始,拷贝2个字节的内容到data数组中
buf.getBytes(0, data);
System.out.println("content of data[0]:" + data[0]);
System.out.println("content of data[1]:" + data[1]);
System.out.println("-----------------------------");
// 修改buffer第1个字节的内容
buf.setByte(0, 0x16);
System.out.println("buf.getByte(0):" + buf.getByte(0));
// 修改buffer的内容不会改变数组的内容
System.out.println("content of data[0]:" + data[0]);
System.out.println("content of data[1]:" + data[1]);
}
}
运行输出:
content of data[0]:10
content of data[1]:11
-----------------------------
buf.getByte(0):22
content of data[0]:10
content of data[1]:11
用writeShort(int value)写入一个short型整数,用getShort(int index)读取一个short型整数
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(4);
buf.writeShort(2048);
// 从buf中读取一个short型整数并打印出来,看是否和传入的相同
System.out.println("从ByteBuf中读取的short型整数为:" + buf.getShort(0));
}
}
运行结果:
写入数据少,读出数据多,但只要没有超过ByteBuf的容量,就不会抛异常
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(10);
buf.writeByte(0x68); // 写入1个字节
System.out.println("current capacity: " + buf.capacity()); // 当前容量是10个字节
System.out.println(buf.getByte(0)); // 读1个字节0x68,结果正确
System.out.println(buf.getShort(0)); // 读2个字节0x6800,结果不正确了
System.out.println(buf.getLong(0)); // 读8个字节0x6800000000000000,结果不正确了
}
}
输出:
current capacity: 10
104
26624
7493989779944505344
从上面的输出结果可以看出,写入少,读出多,只要没有超过ByteBuf的容量,尽管不会抛异常,但结果已经不正确了。
换一种读出方法,用低端字节序读出:
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
ByteBuf buf = Unpooled.buffer(10);
buf.writeByte(0x68);
System.out.println("current capacity: " + buf.capacity());
System.out.println(buf.getByte(0)); // 读1个字节0x68
System.out.println(buf.getShortLE(0)); // 读2个字节0x0068
System.out.println(buf.getLongLE(0)); // 读8个字节0x0000000000000068
}
}
输出结果:
current capacity: 10
104
104
104
用writeBytes(ByteBuf src)函数将源ByteBuf 的数据写入本ByteBuf 中
writeBytes(ByteBuf src)函数的参数是源ByteBuf。
该函数将源ByteBuf中的内容写到本ByteBuf 中。数据传递完成后,源ByteBuf的readerIndex增长传递的字节数,本ByteBuf的writerIndex增长传递的字节数。
如果本ByteBuf的容量不够,会试图扩大容量。
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class Test {
public static void main(String[] args) {
// 创建一个ByteBuf
ByteBuf srcBuf = Unpooled.buffer();
// 写入10个字节
for (int i = 0; i < 10; i++) {
srcBuf.writeByte(0x68);
}
// 创建一个ByteBuf
ByteBuf dstBuf = Unpooled.buffer();
dstBuf.writeBytes(srcBuf);
System.out.println("srcBuf.readerIndex: " + srcBuf.readerIndex());
System.out.println("srcBuf.writerIndex: " + srcBuf.writerIndex());
System.out.println("dstBuf.readerIndex: " + dstBuf.readerIndex());
System.out.println("dstBuf.writerIndex: " + dstBuf.writerIndex());
}
}
运行输出:
srcBuf.readerIndex: 10
srcBuf.writerIndex: 10
dstBuf.readerIndex: 0
dstBuf.writerIndex: 10
getByte(int index)和getUnsignedByte(int index)的对比
package com.thb;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ByteProcessor;
public class Test {
public static void main(String[] args) {
// 创建一个ByteBuf
ByteBuf buf = Unpooled.buffer();
byte b = (byte)0xfe;
// 写入数据
buf.writeByte(b);
// 用两种方法分别读出数据
System.out.println("buf.getByte: " + buf.getByte(buf.readerIndex()));
System.out.println("buf.getUnsignedByte: " + buf.getUnsignedByte(buf.readerIndex()));
}
}
运行输出:
buf.getByte: -2
buf.getUnsignedByte: 254