Netty:ByteBuf写入数据、读出数据

介绍

  • 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
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值