- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
作为Java世界使用最广泛的网络通信框架Netty,其性能和效率是有目共睹的,好多大公司都在使用如苹果、谷歌、Facebook、Twitter、阿里巴巴等,所以不仅仅是因为Netty有高效的性能与效率,更重要的是:屏蔽了底层的复杂度,简单易懂的编程模型,适应更广泛的应用场景,以及活跃的开发者社区。 本篇博客是作为 Netty之数据编码 的续篇,上一篇以抛砖引玉的方式讲解了怎么使用Netty的核心缓冲区ByteBuf怎么编码存储各种基本数据,本篇就是与之对应的怎么从缓冲区ByteBuf中的编码数据解码出来,因为我们的Java代码中处理数据一般不是按照字节流来处理,所以需要解码恢复出数据然后再进行处理.
1 package com.ethan.cws.common.utils; 2 3 import com.ethan.cws.common.enums.TypeEnum; 4 import io.netty.buffer.ByteBuf; 5 import io.netty.buffer.ByteBufUtil; 6 import io.netty.util.CharsetUtil; 7 8 import java.util.ArrayList; 9 import java.util.Arrays; 10 import java.util.List; 11 12 /** 13 * 解码工具类 14 * 15 * @author ethancws 16 * @date 17 */ 18 public final class DecodeUtils { 19 20 /** 21 * FEP data数据文件后缀名 22 */ 23 public final static String FILE_SUFFIX_EXTEND = ".xml" ; 24 25 /** 26 * 文件名 27 */ 28 public final static String FILE_NAME = "Filename" ; 29 30 private DecodeUtils() { 31 32 } 33 34 /** 35 * 解码 36 * 37 * @param symbol 符号 38 * @param byteNum 字节数 39 * @param buff 数据 40 * @param type 枚举类型字符串 41 * @param endian 编码 42 * @return 解码数据 43 */ 44 public static Object decode(String symbol, int byteNum, ByteBuf buff, 45 String type, boolean endian) { 46 Object value = null ; 47 // 类型枚举 48 final TypeEnum typeEnum = TypeEnum.match(type); 49 switch (typeEnum) { 50 case TYPE_STRING: 51 case TYPE_ENUM_STRING: 52 case TYPE_DATE_STRING: 53 value = readString(byteNum, buff, symbol); 54 break ; 55 case TYPE_HEX_STRING: 56 case TYPE_ENUM_HEX_STRING: 57 value = readHexString(byteNum, buff); 58 break ; 59 case TYPE_USHORT: 60 value = readUnSignShort(buff, endian); 61 break ; 62 case TYPE_SHORT: 63 value = readShort(buff, endian); 64 break ; 65 case TYPE_INT: 66 case TYPE_ENUM_INT: 67 value = readInt(buff, endian); 68 break ; 69 case TYPE_UINT: 70 value = readUnSignInt(buff, endian); 71 break ; 72 case TYPE_BYTE: 73 case TYPE_ENUM_BYTE: 74 value = readByte(buff); 75 break ; 76 case TYPE_UBYTE: 77 value = readUnSignByte(buff); 78 break ; 79 case TYPE_BIT: 80 value = readBit(byteNum, buff); 81 break ; 82 case TYPE_MULTI_BIT: 83 value = readMultiBit(byteNum, buff); 84 break ; 85 case TYPE_BCD8421: 86 value = readBcd8421(byteNum, buff); 87 break ; 88 89 } 90 91 return value; 92 } 93 94 /** 95 * 读无符号byte 96 * 97 * @param buff 编码数据 98 * @return 解码数据 99 */ 100 public static short readUnSignByte(ByteBuf buff) { 101 byte by = buff.readByte(); 102 return ( short ) (by & 0x0FF ); 103 } 104 105 /** 106 * 读byte 107 * 108 * @param buff 编码数据 109 * @return 解码数据 110 */ 111 public static byte readByte(ByteBuf buff) { 112 return buff.readByte(); 113 } 114 115 /** 116 * 读无符号int 117 * 118 * @param buff 编码数据 119 * @param endian 字节序 120 * @return 解码数据 121 */ 122 public static long readUnSignInt(ByteBuf buff, boolean endian) { 123 int intValue = endian ? buff.readIntLE() : buff.readInt(); 124 return intValue & 0x0FFFFFFFFL ; 125 } 126 127 /** 128 * 读int 129 * 130 * @param buff 编码数据 131 * @param endian 字节序 132 * @return 解码数据 133 */ 134 public static int readInt(ByteBuf buff, boolean endian) { 135 return endian ? buff.readIntLE() : buff.readInt(); 136 } 137 138 /** 139 * 读short 140 * 141 * @param buff 编码数据 142 * @param endian 字节序 143 * @return 解码数据 144 */ 145 public static short readShort(ByteBuf buff, boolean endian) { 146 return endian ? buff.readShortLE() : buff.readShort(); 147 } 148 149 /** 150 * 读无符号short 151 * 152 * @param buff 编码数据 153 * @param endian 字节序 154 * @return 解码数据 155 */ 156 public static int readUnSignShort(ByteBuf buff, boolean endian) { 157 short shortValue = endian ? buff.readShortLE() : buff.readShort(); 158 return shortValue & 0x0FFFF ; 159 } 160 161 /** 162 * 读Hex字符串 163 * 164 * @param num 字节长度 165 * @param buff 编码数据 166 * @return 字符串 167 */ 168 public static String readHexString( int num, ByteBuf buff) { 169 String value = ByteBufUtil.hexDump(buff, 0 , num); 170 readByteBuf(num, buff); 171 return value; 172 } 173 174 /** 175 * 读Hex字符串没有数据缓冲区偏移 176 * 177 * @param num 字节长度 178 * @param buff 编码数据 179 * @return 字符串 180 */ 181 public static String readHexStringWithoutOffset( int num, ByteBuf buff) { 182 return ByteBufUtil.hexDump(buff, 0 , num); 183 } 184 185 /** 186 * 获取文件名称 187 * 188 * @param fileName 字符 189 * @return 文件名称 190 */ 191 private static String acquireFileName(String fileName) { 192 String fileSuffixExtend = FILE_SUFFIX_EXTEND; 193 int index = fileName.lastIndexOf(fileSuffixExtend); 194 index += fileSuffixExtend.length(); 195 fileName = fileName.substring(1 , index); 196 return fileName; 197 } 198 199 /** 200 * 读字符串 201 * 202 * @param num 字节长度 203 * @param buff 编码数据 204 * @param symbol 编码标识 205 * @return 字符串 206 */ 207 public static String readString( int num, ByteBuf buff, String symbol) { 208 final CharSequence charSequence = buff.getCharSequence(0 , num, CharsetUtil.UTF_8); 209 String value = charSequence.toString(); 210 if (FILE_NAME.equals(symbol)) { 211 value = acquireFileName(value); 212 } 213 // 移动读指针 214 readByteBuf(num, buff); 215 return value; 216 } 217 218 219 /** 220 * 移动读指针 221 * 222 * @param num 移动字节数 223 * @param buff 数据缓冲区ByteBuf 224 */ 225 private static void readByteBuf( int num, ByteBuf buff) { 226 assert num >= 1 ; 227 if (num == 1 ) { 228 buff.readByte(); 229 } else { 230 buff.readBytes(num); 231 } 232 } 233 234 /** 235 * 读bit 236 * 237 * @param num 字节长度 238 * @param buff 数据缓冲区ByteBuf 239 * @return bit位索引 240 */ 241 public static int readBit( int num, ByteBuf buff) { 242 ByteBuf buffCopy = buff.copy(0 , num); 243 int index = 0 ; 244 for (; num > 0; num-- ) { 245 byte b = buffCopy.readByte(); 246 if (b != 0 ) { 247 index += b / 2 ; 248 -- num; 249 break ; 250 } 251 } 252 index += num * 8 ; 253 // 移动读指针 254 readByteBuf(num, buff); 255 return index; 256 } 257 258 /** 259 * 读多位bit 260 * 261 * @param num 字节长度 262 * @param buff 数据缓冲区ByteBuf 263 * @return 二进制数据为1的索引数组 264 */ 265 public static int [] readMultiBit( int num, ByteBuf buff) { 266 ByteBuf buffCopy = buff.copy(0 , num); 267 List<Integer> list = new ArrayList<> (); 268 int size = num; 269 final int fixedNum = num; 270 for (; num > 0; num-- ) { 271 size-- ; 272 int b = readUnSignByte(buffCopy); 273 if (b != 0 ) { 274 String str = Integer.toBinaryString(b); 275 str = fullFillByteString(str); 276 gatherIndexes(str, size, list); 277 } 278 } 279 // 移动读指针 280 readByteBuf(fixedNum, buff); 281 return Arrays.stream(list.toArray( new Integer[0 ])).mapToInt(Integer::valueOf).toArray(); 282 } 283 284 /** 285 * 补全byte二进制8位字符串 286 * 287 * @param str 字符串 288 * @return 补全8位后的字符串 289 */ 290 private static String fullFillByteString(String str) { 291 int len = 8 ; 292 int length = str.length(); 293 if (length < 8 ) { 294 StringBuilder strBuilder = new StringBuilder(str); 295 for ( int i = 0; i < len - length; i++ ) { 296 strBuilder.insert(0, "0" ); 297 } 298 str = strBuilder.toString(); 299 } 300 return str; 301 } 302 303 /** 304 * 收集索引存入List 305 * 306 * @param str byte二进制字符串 307 * @param size 剩余byte长度 308 * @param list 集合List 309 */ 310 private static void gatherIndexes(String str, int size, List<Integer> list) { 311 int len = 8, lenFixed = 8 ; 312 for ( char ch : str.toCharArray()) { 313 int totalIndex = 0 ; 314 len-- ; 315 if (ch == 48 ) { 316 continue ; 317 } 318 totalIndex = len + size * lenFixed; 319 list.add(totalIndex); 320 } 321 } 322 323 /** 324 * 读Bcd码 325 * 326 * @param num 字节长度 327 * @param buff 数据缓冲区ByteBuf 328 * @return Bcd码解码数据 329 */ 330 public static String readBcd8421( int num, ByteBuf buff) { 331 return readHexString(num, buff); 332 } 333 }
。
1 package com.ethan.cws.common.enums; 2 3 /** 4 * 数据枚举 5 * 6 * @author ethancws 7 * @date 8 */ 9 public enum TypeEnum { 10 /** 11 * 字符串 12 */ 13 TYPE_STRING("string" ), 14 15 /** 16 * Binary-Coded Decimal 17 * bcd码 8421码 18 * 4位二进制数表示1位十进制数 19 */ 20 TYPE_BCD8421("bcd8421" ), 21 /** 22 * 时间字符串 23 */ 24 TYPE_DATE_STRING("date_string" ), 25 /** 26 * 枚举byte 27 */ 28 TYPE_ENUM_BYTE("enum|byte" ), 29 30 /** 31 * 枚举int 32 */ 33 TYPE_ENUM_INT("enum|int" ), 34 35 /** 36 * 枚举字符串 37 */ 38 TYPE_ENUM_STRING("enum|string" ), 39 40 /** 41 * 枚举HEX字符串 42 */ 43 TYPE_ENUM_HEX_STRING("enum|hex_string" ), 44 45 /** 46 * HEX字符串 47 */ 48 TYPE_HEX_STRING("hex_string" ), 49 50 /** 51 * -2^31~2^31-1 52 * -2,147,483,648~2,147,483,647 53 */ 54 TYPE_INT("int" ), 55 /** 56 * 0~2^32 57 * 0~4294967296L 58 */ 59 TYPE_UINT("uint" ), 60 /** 61 * -2^15~2^15-1 62 * -32768~32767 63 */ 64 TYPE_SHORT("short" ), 65 /** 66 * 0~65535 67 */ 68 TYPE_USHORT("ushort" ), 69 /** 70 * -2^7~2^7-1 71 * -128~127 72 */ 73 TYPE_BYTE("byte" ), 74 75 /** 76 * 0~256 77 */ 78 TYPE_UBYTE("ubyte" ), 79 80 /** 81 * 多位同选 82 */ 83 TYPE_MULTI_BIT("multi_bit" ), 84 /** 85 * 位 86 */ 87 TYPE_BIT("bit" ); 88 89 private String val; 90 91 TypeEnum(String val) { 92 this .val = val; 93 } 94 95 96 /** 97 * 字符串匹配枚举类型 98 * 99 * @param value 字符串 100 * @return 对应枚举 101 */ 102 public static TypeEnum match(String value) { 103 String str = "TYPE_" ; 104 if (value.indexOf("|") > 0 ) { 105 value = value.replace("|", "_" ); 106 } 107 str += value.toUpperCase(); 108 return valueOf(str); 109 } 110 111 112 }
随着对于Netty的理解和使用的深入,越来越对于Netty框架的痴迷,所以后面会不定期的更新Netty相关的使用与心得。欢迎与大家一起探讨一起学习.
最后此篇关于Netty之数据解码的文章就讲到这里了,如果你想了解更多关于Netty之数据解码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
初学者 android 问题。好的,我已经成功写入文件。例如。 //获取文件名 String filename = getResources().getString(R.string.filename
我已经将相同的图像保存到/data/data/mypackage/img/中,现在我想显示这个全屏,我曾尝试使用 ACTION_VIEW 来显示 android 标准程序,但它不是从/data/dat
我正在使用Xcode 9,Swift 4。 我正在尝试使用以下代码从URL在ImageView中显示图像: func getImageFromUrl(sourceUrl: String) -> UII
我的 Ubuntu 安装 genymotion 有问题。主要是我无法调试我的数据库,因为通过 eclipse 中的 DBMS 和 shell 中的 adb 我无法查看/data/文件夹的内容。没有显示
我正在尝试用 PHP 发布一些 JSON 数据。但是出了点问题。 这是我的 html -- {% for x in sets %}
我观察到两种方法的结果不同。为什么是这样?我知道 lm 上发生了什么,但无法弄清楚 tslm 上发生了什么。 > library(forecast) > set.seed(2) > tts lm(t
我不确定为什么会这样!我有一个由 spring data elasticsearch 和 spring data jpa 使用的类,但是当我尝试运行我的应用程序时出现错误。 Error creatin
在 this vega 图表,如果我下载并转换 flare-dependencies.json使用以下 jq 到 csv命令, jq -r '(map(keys) | add | unique) as
我正在提交一个项目,我必须在其中创建一个带有表的 mysql 数据库。一切都在我这边进行,所以我只想检查如何将我所有的压缩文件发送给使用不同计算机的人。基本上,我如何为另一台计算机创建我的数据库文件,
我有一个应用程序可以将文本文件写入内部存储。我想仔细看看我的电脑。 我运行了 Toast.makeText 来显示路径,它说:/数据/数据/我的包 但是当我转到 Android Studio 的 An
我喜欢使用 Genymotion 模拟器以如此出色的速度加载 Android。它有非常好的速度,但仍然有一些不稳定的性能。 如何从 Eclipse 中的文件资源管理器访问 Genymotion 模拟器
我需要更改 Silverlight 中文本框的格式。数据通过 MVVM 绑定(bind)。 例如,有一个 int 属性,我将 1 添加到 setter 中的值并调用 OnPropertyChanged
我想向 Youtube Data API 提出请求,但我不需要访问任何用户信息。我只想浏览公共(public)视频并根据搜索词显示视频。 我可以在未经授权的情况下这样做吗? 最佳答案 YouTube
我已经设置了一个 Twilio 应用程序,我想向人们发送更新,但我不想回复单个文本。我只是想让他们在有问题时打电话。我一切正常,但我想在发送文本时显示传入文本,以确保我不会错过任何问题。我正在使用 p
我有一个带有表单的网站(目前它是纯 HTML,但我们正在切换到 JQuery)。流程是这样的: 接受用户的输入 --- 5 个整数 通过 REST 调用网络服务 在服务器端运行一些计算...并生成一个
假设我们有一个名为 configuration.js 的文件,当我们查看内部时,我们会看到: 'use strict'; var profile = { "project": "%Projec
这部分是对 Previous Question 的扩展我的: 我现在可以从我的 CI Controller 成功返回 JSON 数据,它返回: {"results":[{"id":"1","Sourc
有什么有效的方法可以删除 ios 中 CBL 的所有文档存储?我对此有疑问,或者,如果有人知道如何从本质上使该应用程序像刚刚安装一样,那也会非常有帮助。我们正在努力确保我们的注销实际上将应用程序设置为
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我正在为服务于发布请求的 API 调用运行单元测试。我正在传递请求正文,并且必须将响应作为帐户数据返回。但我只收到断言错误 注意:数据是从 Azure 中获取的 spec.js const accou
我是一名优秀的程序员,十分优秀!