org.apache.hadoop.io.WritableUtils
1 public static void writeVLong(DataOutput stream, long i) throws IOException 2 { 3 // 直接写数据 4 if (i >= -112 && i <= 127) { 5 stream.writeByte((byte) i); 6 return; 7 } 8 9 int len = -112; 10 11 // 当操作数据为负数 12 if (i < 0) { 13 i ^= -1L; // i ^ 111111111... 相当于(-i - 1) 14 len = -120; 15 } 16 17 // 循环取最高位长度 18 long tmp = i; 19 while (tmp != 0) { 20 tmp = tmp >> 8; 21 len--; 22 } 23 24 // 写入长度标识 25 stream.writeByte((byte) len); 26 27 // 计算需写入的字节长度 28 len = (len < -120) ? -(len + 120) : -(len + 112); 29 30 for (int idx = len; idx != 0; idx--) { 31 int shiftbits = (idx - 1) * 8; // 屏蔽长度 32 long mask = 0xFFL << shiftbits; // 255 << ((idx -1) * 8) 33 stream.writeByte((byte) ((i & mask) >> shiftbits)); 34 } 35 }
1 // 判断是否为负值 2 public static boolean isNegativeVInt(byte value) 3 { 4 return value < -120 || (value >= -112 && value < 0); 5 } 6 7 // 解析写入时的长度标识 8 public static int decodeVIntSize(byte value) 9 { 10 if (value >= -112) return 1; 11 else if (value < -120) return -119 - value; 12 return -111 - value; 13 } 14 15 16 public static long readVLong(DataInput stream) throws IOException 17 { 18 byte firstByte = stream.readByte(); 19 int len = decodeVIntSize(firstByte); 20 21 if (len == 1) { 22 return firstByte; 23 } 24 25 long i = 0; 26 for (int idx = 0; idx < len - 1; idx++) { 27 byte b = stream.readByte(); 28 i = i << 8; // 00000000 每次向左移8位 29 i = i | (b & 0xFF); // i | (b & 11111111) 30 } 31 32 // 如果为负数则^-1L 33 return (isNegativeVInt(firstByte) ? (i ^ -1L) : i); 34 }