字节 - >原始不一致,尝试创建缓冲区

时间:2014-11-28 01:47:04

标签: java io

我试图制作一个定制的缓冲区,该缓冲区将使用List<Byte>,目前我只能在完全崩溃之前获得一个方法我,我不确定为什么。我一直在引用DataOutputStreamDataInputStream类的源代码,以确保我正确地读/写数据。

我一定是做错了。

    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);
}

1 个答案:

答案 0 :(得分:1)

Java中的类型byte是有符号的,就像所有具有数字语义的原始类型一样(char是唯一的例外,但我不会调用char数字语义。与绝大多数设备一样,Java使用两个补码来存储值。

因此,字节的值范围是-128127,这里是一些相应的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;