首页 » SEO优化 » phpstrtobytes技巧_netty系列之netty中的核心编码器bytes数组

phpstrtobytes技巧_netty系列之netty中的核心编码器bytes数组

访客 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

对付byte数组来说,如果每次都将其封装进ByteBuf中,再进行传输显得有些麻烦。
于是netty供应了一个基于bytes的核心编码解码器。

byte是什么

那么byte是什么呢? byte表示的是一个字节,也便是8bits。
用二进制表示便是-128-127的范围。
byte是JAVA中的根本类型。

phpstrtobytes技巧_netty系列之netty中的核心编码器bytes数组

同时它还有一个wrap类型叫做Byte。

phpstrtobytes技巧_netty系列之netty中的核心编码器bytes数组
(图片来自网络侵删)

先看下Byte的定义:

public final class Byte extends Number implements Comparable<Byte>

Byte中定义了byte的取值访问:

public static final byte MIN_VALUE = -128; public static final byte MAX_VALUE = 127;

并且还供应了一些基本的工具方法。

由于byte表示的是一个8bits的二进制,如果不算位运算的话,byte基本上是JAVA中最小的数据存储单位了。
以是JAVA中所有的工具都可以转换成为byte。

根本类型的转换这里就不多讲了。
这里紧张看一下字符串String和工具Object和byte数组之间的转换。

先来看下字符串String和byte数组之间的转换,也便是String和二进制之间的转换。

基本的转换思路便是将String中的字符进行编码,然后将编码过后的字符进行存储即可。

String类本身供应了一个getBytes方法,可以接管编码类型,以UTF-8来说,我们来看下转换方法的调用:

public static byte[] stringToBytes(String str) throws UnsupportedEncodingException { return str.getBytes("utf-8"); } public static String bytesToString(byte[] bs) throws UnsupportedEncodingException { return new String(bs, "utf-8"); }

直接调用String中的方法即可。

如果是Object工具的话,由于Object本身并没有供应转换的方法,以是我们须要借助于ByteArrayOutputStream的toByteArray方法和ByteArrayInputStream的readObject方法来实现byte数组和Object之间的转换,如下所示:

//工具转数组 public byte[] toByteArray (Object obj) throws IOException { try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos)) { oos.writeObject(obj); oos.flush(); return bos.toByteArray(); } } //数组转工具 public Object toObject (byte[] bytes) throws IOException, ClassNotFoundException { try ( ByteArrayInputStream bis = new ByteArrayInputStream (bytes); ObjectInputStream ois = new ObjectInputStream (bis)) { return ois.readObject(); } }netty中的byte数组的工具类

netty中的核心是ByteBuf,ByteBuf供应了大部分根本数据类型的read和write方法。
当然如果要读取工具,那么还是须要将工具转换成为byte然后再写入或者从ByteBuf中读出。

当然,netty中不须要这么繁芜,netty供应了一个Unpooled的工具类用来方便的将byte数组和ByteBuf进行转换。

先看下Unpooled方法供应的ByteBuff构建方法:

ByteBuf heapBuffer = buffer(128); ByteBuf directBuffer = directBuffer(256); ByteBuf wrappedBuffer = wrappedBuffer(new byte[128], new byte[256]); ByteBuf copiedBuffer = copiedBuffer(ByteBuffer.allocate(128));

这是Unpooled供应的几种ByteBuf的构建办法,个中heapBuffer表示的是在用户空间构建的buff,directBuffer表示的是直接在系统空间构建的buff。
wrappedBuffer是对现有的byte数组和ByteBuf之上构建的视图,而copiedBuffer是对byte数组,byteBuf和字符串的拷贝。

这里我们须要用到wrappedBuffer方法,将byte数组封装到ByteBuf中:

public static ByteBuf wrappedBuffer(byte[] array) { if (array.length == 0) { return EMPTY_BUFFER; } return new UnpooledHeapByteBuf(ALLOC, array, array.length); }

wrappedBuffer返回了一个UnpooledHeapByteBuf工具,这个工具本身便是一个ByteBuf。
这里将byte数组作为布局函数传入UnpooledHeapByteBuf中。

这里的array是UnpooledHeapByteBuf中的私有变量:

byte[] array;

除告终构函数,UnpooledHeapByteBuf还供应了一个setArray的方法用来设置byte数组:

private void setArray(byte[] initialArray) { array = initialArray; tmpNioBuf = null; }

下面是如何从array中构建ByteBuf:

public ByteBuf setBytes(int index, ByteBuffer src) { ensureAccessible(); src.get(array, index, src.remaining()); return this; }

从ByteBuf中读取byte数组,可以调用ByteBufUtil的getBytes方法:

public static byte[] getBytes(ByteBuf buf) { return getBytes(buf, buf.readerIndex(), buf.readableBytes()); }netty中byte的编码器

万事俱备只欠东风,有了上面netty供应的工具类,我们就可以利用这些工具类构建基于byte的编码器了。

netty中基于byte的编码解码器分别叫做ByteArrayEncoder和ByteArrayDecoder。

先来看下这两个类是如何利用的,这里以一个范例的TCP/IP运用为例:

ChannelPipeline pipeline = ...; // Decoders pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4)); pipeline.addLast("bytesDecoder", new ByteArrayDecoder()); // Encoder pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)); pipeline.addLast("bytesEncoder", new ByteArrayEncoder());

这里的LengthFieldBasedFrameDecoder和LengthFieldPrepender因此长度为分割标准的frame分割器。
这里我们紧张关注ChannelPipeline中添加的ByteArrayDecoder和ByteArrayEncoder。

添加了byte的编码和解码器之后,就可以直接在handler中直策应用byte数组,如下所示:

void channelRead(ChannelHandlerContext ctx, byte[] bytes) { ... }

先来看下ByteArrayEncoder,这是一个编码器,它的实现很大略:

public class ByteArrayEncoder extends MessageToMessageEncoder<byte[]> { @Override protected void encode(ChannelHandlerContext ctx, byte[] msg, List<Object> out) throws Exception { out.add(Unpooled.wrappedBuffer(msg)); }}

详细便是利用Unpooled.wrappedBuffer方法byte数组封装成为ByteBuf,然后将其添加到out list中。

同样的,我们不雅观察一下ByteArrayDecoder,这是一个解码器,实现也比较大略:

public class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf> { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception { // copy the ByteBuf content to a byte array out.add(ByteBufUtil.getBytes(msg)); }}

详细的实现便是调用ByteBufUtil.getBytes方法,将ByteBuf转换成为byte数组,然后添加到list工具中。

总结

如果要在netty中传输二进制数据,netty供应的byte编码和解码器已经封装了繁琐的细节,大家可以放心利用。

本文已收录于 http://www.flydean.com/14-2-netty-codec-bytes/

最普通的解读,最深刻的干货,最简洁的教程,浩瀚你不知道的小技巧等你来创造!

欢迎关注我的"大众号:「程序那些事」,懂技能,更懂你!

标签:

相关文章

介绍百度网盘,云端存储时代的创新先锋

随着互联网技术的飞速发展,云计算已经成为现代生活不可或缺的一部分。而在这其中,百度网盘作为国内领先的云存储服务提供商,以其卓越的性...

SEO优化 2025-01-03 阅读1 评论0

介绍监控屏蔽技术,守护个人隐私的利器

随着科技的发展,监控设备已经深入到我们生活的方方面面。在享受便利的隐私安全问题也日益凸显。如何有效屏蔽监控,保护个人隐私,成为人们...

SEO优化 2025-01-03 阅读1 评论0

介绍番号观看方法,轻松驾驭影视世界

随着互联网的普及,网络影视资源日益丰富,番号作为影视作品的标识码,已经成为广大观众了解、搜索和观看影视作品的重要途径。如何正确地使...

SEO优化 2025-01-03 阅读1 评论0

介绍盗微信号黑幕,网络安全的严峻挑战

在数字化时代,微信已成为人们生活中不可或缺的通讯工具。随着微信用户数量的激增,盗微信号的事件也日益增多。本文将深入剖析盗微信号的方...

SEO优化 2025-01-03 阅读1 评论0