理论部分
一个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%空间