在Netty 3中,我们使用LITTLE_ENDIAN ChannelBuffers在每一端强制执行
bootstrap.setOption("child.bufferFactory", new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN));
但在Netty 4中,ByteBuf的配置现在似乎是通过ChannelOption.ALLOCATOR:
bootstrap.option(ChannelOption.ALLOCATOR, someAllocator);
我们真正想做的是装饰UnpooledByteBufAllocator,但它是最终的和方法我们需要装饰是受保护的,所以我们不能扩展类或委托给它。我们有不得不诉诸代理方法:
private static class AllocatorProxyHandler implements InvocationHandler {
private final ByteBufAllocator allocator;
public AllocatorProxyHandler(ByteBufAllocator allocator) {
this.allocator = allocator;
}
public static ByteBufAllocator proxy(ByteBufAllocator allocator) {
return (ByteBufAllocator) Proxy.newProxyInstance(AllocatorProxyHandler.class.getClassLoader(), new Class[]{ByteBufAllocator.class}, new AllocatorProxyHandler(allocator));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(allocator, args);
if (result instanceof ByteBuf) {
return ((ByteBuf) result).order(ByteOrder.LITTLE_ENDIAN);
} else {
return result;
}
}
}
像这样设置引导选项:
bootstrap.option(ChannelOption.ALLOCATOR, AllocatorProxyHandler.proxy(UnpooledByteBufAllocator.DEFAULT));
有没有其他(更好)的方法可以做到这一点,我们错过了?
Netty 4.0的ByteBuf
默认是大端序的。 您可以使用 order(ByteOrder)
方法获取ByteBuf
的小端视图:
ByteBuf buf = ctx.alloc().buffer();
ByteBuf leBuf = buf.order(ByteOrder.LITTLE_ENDIAN);
leBuf.getByte(...);
...
这是设计使然,以避免将字节顺序保留为状态变量而导致的任何混淆。 如果有充分的理由说明为什么它必须提供一种更改默认字节顺序的方法,请告诉我们,以便我们可以重新考虑此决定。