Java 净读取字节的确切数目
我正在扩展,希望读取确切的字节数Java 净读取字节的确切数目,java,netty,Java,Netty,我正在扩展,希望读取确切的字节数 public class Reader extends ChannelInboundHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf b = (ByteBuf) msg; byte size = b.readByte(); //Now I want to
public class Reader extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg){
ByteBuf b = (ByteBuf) msg;
byte size = b.readByte();
//Now I want to read exactly size bytes from the channel
//and then again read the number of bytes and read the bytes...
}
}
问题是,我们可能会从中读取的字节数少于所需的字节数。如何阅读?仅用于阅读,您可以使用
b.readSlice(大小)
。
但是,正如您所提到的,缓冲区可能还没有足够的数据来存储消息。因此,您需要在创建消息之前完全使用数据。对于这种情况,我建议您使用内置的ByteToMessageDecoder
处理程序。它将为您处理低级字节。因此,使用ByteToMessageDecoder
时,您的代码将如下所示:
class Reader extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
byte size = in.readByte();
if (in.readableBytes() < size) {
in.resetReaderIndex();
return;
}
ByteBuf bb = in.readSlice(size);
//make whatever you want with bb
Message message = ...;
out.add(message);
}
}
类读取器扩展ByteToMessageDecoder{
@凌驾
受保护的无效解码(ChannelHandlerContext ctx、ByteBuf输入、列表输出)引发异常{
字节大小=in.readByte();
if(in.readableBytes()
因此,在本例中,您读取了消息需要读取的字节数-
size
。然后检查缓冲区中的是否有足够的数据可以使用。如果不是,则将控件返回到ByteToMessageDecoder
,直到它读取更多。然后重复,直到有足够的数据来构建消息。事实上,是的。谢谢。但是与之间的区别是什么呢?何时使用哪个?@St.Antario请查看ReplayingDecoder
javadocs。它有一个很好的例子解释。简而言之,ReplayingDecoder
做的更多,您不需要在.readableBytes()。但是,价格是-性能较低。ReplayDecoder可以帮助您处理底层流数据的复杂情况,例如数据不足。如果您不太关心性能,它将大大降低代码逻辑的复杂性。