在tcp协议中,经常会遇到需要在传入的数据中按照指定的分隔符来截取其中的string类型数据的情况。但在百度和google查询后都只找到关于DelimiterBasedFrameDecoder、LineBasedFrameDecoder等decoder类的使用介绍,通过阅读LineBasedFrameDecoder类的代码,写了一个根据0x00分隔符,截取string数据的方法。netty版本为4.1.29.Final。通过该方法可以比较便捷、高效的获取String类型数据。
/**
* 从ByteBuf读取string数据,默认读取到0x00字节,返回string数据,并将readerIndex置为0x00所在位置
* @param in
* @return String
*/
private static String readString(ByteBuf in) {
int totalLength = in.readableBytes();
//判断是否有可读数据
if (totalLength > 0) {
int index = in.forEachByte(in.readerIndex(), totalLength, ByteProcessor.FIND_NUL);
//判断是否存在0x00字节
if (index > -1) {
//判断是否只有0x00字节
if (index == 0) {
in.skipBytes(1);
} else {
int length = index - in.readerIndex();
ByteBuf frame = in.readSlice(length);
in.skipBytes(1);
byte[] req = new byte[frame.readableBytes()];
frame.readBytes(req);
return new String(req);
}
}
}
return null;
}
昨天在阅读《Netty In Action》的时候发现,从ByteBuf中提取字符串可以使用toString(charset)方法,内存利用率应该高于直接通过byte[]拷贝,所以上述代码的最后三行可以改为:return frame.toString(CharsetUtil.UTF_8);