由于需要写了两个将int型与byte[]数组相互转换的方法,将int型转变成byte[]数组还好说,将byte[]数组转换回int就出现问题了。
将int转换成byte[]数组的方法代码如下:
public static byte[] intToBytes(int origin) {
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
bytes[3 - i] = (byte) (origin >>> (i * 8));
}
return bytes;
}
思路是将int型数据的32位分别存储进4个byte中。对int型做强制转换(byte),会将int型的高24位截掉,只保留低8位。因此将一个整型向右位移8位,然后强制转换成byte型,就能得到一个保存这个整型中间8位的byte数值,以此类推得到4个byte,构成数组。
将byte[]数组转换回int的方法代码如下:
public static int bytesToInt(byte[] bytes) {
if (bytes.length != 4)
throw new IllegalArgumentException(
"bytes should be a 4-length byte array");
int i = bytes[0];
for (int p = 1; p < 4; p++) {
i = i << 8;
System.out.println(i);
i = i | bytes[p];
}
return i;
}
思路是与上一个方法反过来,将每个byte转换成int,得到的int数据只有低8位对应于原byte,高24位全部为0(这是错的),将这个int左移相应位数(8的0、1、2、3倍)得到的新int数据,它对应于目标int型数据的某8位。四个byte对应四个8位,按位或后得到目标int。
测试代码如下:
public static void main(String[] args) throws IOException {
int origin = 91825;
byte[] bytes = intToBytes(origin);
for (int i = 0; i < 4; i++) {
System.out.print(bytes[i] + " ");
}
System.out.println();
System.out.println("bytesToInt(bytes)结果:" + bytesToInt(bytes));
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(bais);
System.out.println("readInt()结果:" + dis.readInt());
}
结果如下:0 1 102 -79
0
256
91648
bytesToInt(bytes)结果:91569
readInt()结果:91825
从结果中可已看出,int型数据91825转变成的byte[]数组,经过DataInputStream的readInt()方法读取后,正确还原成了91825,说明转变成的byte[]数组没有错。
但是bytesToInt()方法的结果却错了。
根据bytesToInt()方法打印的输出可以发现对91825的高24位所对应的3个byte进行还原时都没有错误,只有对它的最低8位构成的byte数值:-79进行还原操作时除了差错。91648 - 79 = 91569。
错误原因:分析了老半天,才发现是数据类型转换的原因。将byte转换成int,得到的int数据并不一定低8位对应于原byte而高24位全部为0,比如这个byte为负数的时候,得到的int是补码:比如这个byte为-79,得到的int就是对-79重新进行补码编码后的int,而不是在高24位上加24个0,它的高24位全部为1(本来就应该这样,但是自己把自己绕进去了没想起来)。
if (bytes.length != 4)
throw new IllegalArgumentException(
"bytes should be a 4-length byte array");
int i = bytes[0] & 0xff;
for (int p = 1; p < 4; p++) {
i = i << 8;
System.out.println(i);
i = i | (bytes[p] & 0xff);
}
return i;
}