我试图制作一个定制的缓冲区,该缓冲区将使用List<Byte>
,目前我只能在完全崩溃之前获得一个方法我,我不确定为什么。我一直在引用DataOutputStream和DataInputStream类的源代码,以确保我正确地读/写数据。
我一定是做错了。
private List<Byte> buffer = new ArrayList<>();
public void writeInt(int value) {
buffer.add((byte)((value >>> 24) & 0xFF));
buffer.add((byte)((value >>> 16) & 0xFF));
buffer.add((byte)((value >>> 8) & 0xFF));
buffer.add((byte)((value >>> 0) & 0xFF));
}
public void readInt() {
int ch1 = buffer.get(0);
int ch2 = buffer.get(1);
int ch3 = buffer.get(2);
int ch4 = buffer.get(3);
System.out.println("CH1: " + ch1);
System.out.println("CH2: " + ch2);
System.out.println("CH3: " + ch3);
System.out.println("CH4: " + ch4);
System.out.println("===============");
int value = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
System.out.println("Value: " + value);
}
如果我写一个较小的值(从0-> 127的任何东西),它完全没问题,但是当我达到128时,所有地狱都会失败,这里输出的是127vs128 < / p>
#writeInt(127)
CH1: 0
CH2: 0
CH3: 0
CH4: 127
===============
Value: 127
#writeInt(128)
CH1: 0
CH2: 0
CH3: 0
CH4: -128
===============
Value: 128
只是为了更多(我不理解)示例,这里有很多。 的 #writeInt(999999999)
CH1: 59
CH2: -102
CH3: -55
CH4: -1
===============
Value: 983156991
老实说,我不确定自己哪里出错了,希望有人可以告诉我。
编辑:我也认为这可能是因为我将字节作为int,然后尝试进行数学运算,所以我将其更改了,但它并没有改变结果。修改示例:
public void readInt() {
int ch1 = buffer.get(0) << 24;
int ch2 = buffer.get(1) << 16;
int ch3 = buffer.get(2) << 8;
int ch4 = buffer.get(3) << 0;
System.out.println("CH1: " + ch1);
System.out.println("CH2: " + ch2);
System.out.println("CH3: " + ch3);
System.out.println("CH4: " + ch4);
System.out.println("===============");
int value = (ch1 + ch2 + ch3 + ch4);
System.out.println("Value: " + value);
}
答案 0 :(得分:1)
Java中的类型byte
是有符号的,就像所有具有数字语义的原始类型一样(char
是唯一的例外,但我不会调用char
数字语义。与绝大多数设备一样,Java使用两个补码来存储值。
因此,字节的值范围是-128
到127
,这里是一些相应的2的补码位模式,它们将存储在一个字节中:
-128 -> 1000 0000
-127 -> 1000 0001
-2 -> 1111 1110
-1 -> 1111 1111
0 -> 0000 0000
1 -> 0000 0001
126 -> 0111 1110
127 -> 0111 1111
当您将byte
投射到int
时,这就是当您执行buffer.get()
时隐式发生的事情,因为您使用返回值进行算术运算,它会以符号扩展的方式发生 - 这是它是如何在Java中定义的。
换句话说:
(int) 128 -> 128 (0000 0000 0000 0000 0000 0000 1000 0000)
(byte) (int) 128 -> -128 (---- ---- ---- ---- ---- ---- 1000 0000)
(int) (byte) (int) 128 -> -128 (1111 1111 1111 1111 1111 1111 1000 0000)
您想明确否定符号扩展的影响。您可以在移动值之前使用& 0xFF
来执行此操作。 readInt()
方法的相应部分应如下所示:
int ch1 = buffer.get(0) & 0xFF;
int ch2 = buffer.get(1) & 0xFF;
int ch3 = buffer.get(2) & 0xFF;
int ch4 = buffer.get(3) & 0xFF;