[编织消息框架][设计协议]优化long,int转换

理论部分

一个long占8byte,大多数应用数值不超过int每次传输多4byte会很浪费

有没有什么办法可以压缩long或int呢?

答案是有的,原理好简单,如果数值不超过int.max_value的话就"自动变成"int类型

现在问题又出现了读取时如果知道原来的类型是什么?

可以先写一个byte是什么类型,再写入值,读时先读一个byte,根据类型做不同解释

源码解读

 1 public abstract class PacketUtil {
 2  
 3     public final static byte BIT_8 = Byte.MAX_VALUE;
 4     public final static short BIT_16 = Short.MAX_VALUE;
 5     public final static int BIT_32 = Integer.MAX_VALUE;
 6     public final static long BIT_64 = Long.MAX_VALUE;
 7     /***
 8         读取自适应数字
 9     */
10     public static Number autoReadNum(int offset, byte[] bytes) {
11         byte bit = bytes[offset];
12         offset++;
13         Number ret = null;
14         switch (bit) {
15         case 9:    //readLong
16             ret = readLong(offset, bytes);
17             break;
18         case 5: //readInt
19             ret = readInt(offset, bytes);
20             break;
21         case 3: //readShort
22             ret = readShort(offset, bytes);
23             break;
24         case 2:    //readByte
25             ret = readByte(offset, bytes);
26             break;
27         case 1: //zero
28             ret = (byte) 0;
29             break;
30         default:
31             throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
32         }
33 
34         return ret;
35     }
36     /***
37         写入自适应数字
38     */
39     public static byte autoWriteNum(int offset, Number v, byte[] ret) {
40         byte bit = getAutoWriteLen(v);
41         writeByte(offset, bit, ret);
42         offset++;
43         switch (bit) {
44         case 9:    //writeLong
45             writeLong(offset, v.longValue(), ret);
46             break;
47         case 5: //writeInt
48             writeInt(offset, v.intValue(), ret);
49             break;
50         case 3: //writeShort
51             writeShort(offset, v.shortValue(), ret);
52             break;
53         case 2: //writeByte
54             writeByte(offset, v.byteValue(), ret);
55             break;
56         case 1:  //zero
57             break;
58         default:
59             throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
60         }
61         return bit;
62     }
63     /***
64         获取自适合数字大小
65     */
66     public static byte getAutoWriteLen(Number value) {
67         long v = value.longValue();
68         if (v < 0) {
69             v = -v;
70         }
71         byte bit = 0;
72         //如果为零返回类型为0
73         if (v == 0) {
74             bit = 1;
75         } else if (v > BIT_32) { //如果超过int max 认为是long类型
76             bit = 9;
77         } else if (v > BIT_16) {//如果超过short max 认为是int类型
78             bit = 5;
79         } else if (v > BIT_8) { //如果超过byte max 认为是short类型
80             bit = 3;
81         } else { //否则为byte类型
82             bit = 2;
83         }
84         return bit;
85     }
86 }

如果数值为0时,可以减小到1byte,少于short.max_value 占3byte,减少60%空间

原文地址:https://www.cnblogs.com/solq111/p/6492229.html