java 板


LINE

※ 引述《JGC18 (JGC)》之铭言: : 各位先进好: : 小弟今天有一台设备,假设回应资料的长度会有,250bytes, 120bytes, 60bytes : 这250bytes,假设依照规格总共可以解析出10个栏位(栏位编号为A,B,C,D,E,F,G,H,I,J) : 120bytes,可以解析出6个栏位(栏位编号为 A,D,E,F,I,J) : 60bytes,可以解析出3个栏位 (栏位编号为 B,C,D) : 250个bytes等於是完整的所有资料回覆 : 如果有错误,就是回应120bytes跟60bytes : 我目前想到的方法是用一个class类似这样 在进行设计之前, 可以先思考一下当前需求以及未来有无扩充或改变需求的可能。 依照你的叙述, 每一次回应的资料可能有3种不同的长度, 又分别对应到不同数量和种类的栏位。 首先可以想到的问题是: 未来有没有可能会多一种回应的长度?比如180bytes? 栏位顺序改变 => A,B,C,D -> B,D,A,C 栏位种类改变 => A,B,C,D -> A,B,C,E 栏位型态改变 => int A -> String A 有了一些概念之後才比较可能设计出比较弹性的程式, 未来面对需求改变的时候也比较容易改动。 假设今天这台设备回传的三种不同长度资料分别为, 月收入(250 bytes),固定收入(120 bytes),投资损益(60 bytes)。 从结果来看, 你可能会想要类似这样子的类别。 public class Income{ private String name; private int income; private int salary; private int foodAllowances; private boolean absence; //以下略 public String getName(){ return this.name; } //以下略 } public class Salary{ private int salary; private int foodAllowances; private boolean absence; //以下略 } public class Investment{ //略 } 这三种类别必须要先确定且定义好提供外界存取的方法, 再来思考如何将各个值塞进去。 另外为了保留栏位顺序的弹性, 我们希望这个顺序可以定义在程式以外的地方。 在执行期间读入外部的顺序, 再利用reflection的方式依序将各栏位塞入对应的属性内。 因此我们需要一个父类别帮我们赋予各个属性的值。 public abstract class BaseBean { //栏位及长度 protected abstract LinkedHashMap<String, Integer> getFields(); //index of byte array private int index = 0; public void parse(byte[] input){ try{ for(Entry<String, Integer> entry : this.getFields().entrySet()){ Field field = this.getClass().getField(entry.getKey()); Class<?> clazz = field.getType(); int length = entry.getValue(); Object value = translate(input, clazz, length); field.set(this, value); } }catch (Exception e){ //略 } } protected Object translate(byte[] input, Class<?> clazz, int length){ Object result = null; if(clazz.equals(int.class)){ result = translateToInt(input); }else if(clazz.equals(String.class)){ result = translateToString(input, length); }else{ //略 } return result; } //byte to int private int translateToInt(byte[] input){ final int LENGTH = 4; byte[] cell = Arrays.copyOfRange(input, index, LENGTH); index += LENGTH; int result = 0; //略 return result; } //byte to String private String translateToString(byte[] input, int length){ final int BYTE_LENGTH = 2; final String CHARSET = "unicode"; String result = null; try { result = new String(/*太长省略*/); index += BYTE_LENGTH * length; } catch (UnsupportedEncodingException e) { //略 } return result; } } 接下来只要让Income,Salary,Investment 继承BaseBean, 实作getFields,(读设定档或是直接hard code在程式里) 再由外部程式依照所得阵列长度来初始化其中之一物件即可。 未来若是新增一个180 bytes的input, 只要新增一个子类别, 定义好自身的属性以及栏位的顺序, 就可以很容易的扩充。 若是parse byte array的方式有变也只需更改父类别, 不会对子类别有太大的影响。 -- ▃▃▃▃▃▃▃▃▃▃▃▃▃ ██▃▃▃▃▃▃▃ ▇▇▇ ▇▇▇ ▇ ▇▇█ ▇▇▇ ▇█▇ ▇▇▇ ▇ ▇ █ █ ▉▉█ █ █ █ █ █ █ █ █ ██◤ ███ ▉▉█ █ ███ ███ █ ███ █ ◆│ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄██│ By luh4 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 219.70.196.68
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1431440300.A.ABB.html
1F:推 pttworld: 推,OO威,但高阶语言总是很难跟parsing设备资料联想。 05/13 03:01
2F:→ pttworld: 另外提醒讨论串原po,如果你看得到这篇文。 05/13 03:02
3F:→ pttworld: 机器设备资料的parsing最需要注意的点就是endian问题。 05/13 03:02
4F:→ pttworld: 所以,方法就这篇,讨论串原po先要到format吧。 05/13 03:04
5F:推 JGC18: 非常感谢大大提供这麽有弹性的方法,reflection第一次碰到 05/13 09:48
6F:→ JGC18: 我先把大大的这个方法写一个demo感受一下reflection的威力 05/13 09:48
7F:→ JGC18: 如有不懂在上来请教各位,真的谢谢回覆我问题的前辈们 05/13 09:49
8F:→ qrtt1: 虽然是个好设计,但不确定适不适合原 PO 的情况 05/13 11:38
9F:→ qrtt1: 低阶 parse binary data 的工作通常效能考量大於设计 :P 05/13 11:39
10F:推 Killercat: 这种我大概会建议用JNI call C,用struct mask来做 05/13 16:07
11F:→ Killercat: alignment跟mask根本就是为了处理这种东西而存在的XD 05/13 16:07
12F:→ Killercat: 不过只要有编码问题就是死光光... 05/13 16:08







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP