Java-为固定字节数组赋值

Java-为固定字节数组赋值,java,arrays,integer,byte,Java,Arrays,Integer,Byte,我正在尝试为一个异常的固定大小字节数组(3)分配一个整数值。我看到了ByteBuffers分配特性,但是putInt试图放入4个字节,然后由于溢出而中断 例如: byte[] messageLength = ByteBuffer.allocate(3).putInt(Integer.parseUnsignedInt("300")).array(); 导致以下异常 Exception in thread "main" java.nio.BufferOverflowException at jav

我正在尝试为一个异常的固定大小字节数组(3)分配一个整数值。我看到了ByteBuffers分配特性,但是putInt试图放入4个字节,然后由于溢出而中断

例如:

byte[] messageLength = ByteBuffer.allocate(3).putInt(Integer.parseUnsignedInt("300")).array();
导致以下异常

Exception in thread "main" java.nio.BufferOverflowException
at java.nio.Buffer.nextPutIndex(Buffer.java:527)
at java.nio.HeapByteBuffer.putInt(HeapByteBuffer.java:372)
显然,300可以放入3个字节,因为在二进制中它是0001 0010 1100


如何将完全合法大小的整数值放入非4字节数组?

在字节缓冲区内分配整数需要4字节。 如果需要特殊的解包规则,可以手动读取字节缓冲区

下面是一个例子:

public static byte[] convertInts(int[] source) {
    ByteBuffer buffer = ByteBuffer.allocate(4 * source.length);
    for (int data : source) {
        buffer.putInt(data);
    }
    buffer.flip();

    byte[] destination = new byte[3 * source.length];
    for (int i = 0; i < source.length; i++) {
        buffer.get();
        destination[i * 3] = buffer.get();
        destination[i * 3 + 1] = buffer.get();
        destination[i * 3 + 2] = buffer.get();
    }

    return destination;
}

一个简单的解决方案是将
整数
值转换为只包含必要位的
字节[]
。以下代码使用适合1、2、3和4字节的整数:

private static byte[] compressInteger(int value) {
    if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
        return new byte[] { (byte) value };
    } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
        return new byte[] { (byte) (value >>> 8), (byte) (value) };
    } else if ((byte)(value >>> 24) == 0) {
        return new byte[] { (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    } else {
        return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    }
}

newbyte[]{(byte)(i>>16),(byte)(i>>8),(byte)i}
^----这样做,了解位移位>>我的问题是为什么要这样做?您知道关于数据输出流的信息吗?
private static byte[] compressInteger(int value) {
    if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
        return new byte[] { (byte) value };
    } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
        return new byte[] { (byte) (value >>> 8), (byte) (value) };
    } else if ((byte)(value >>> 24) == 0) {
        return new byte[] { (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    } else {
        return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    }
}
private static int decompressInteger(byte[] bytes) {
    int value = 0;
    for (int i = bytes.length - 1; i >= 0; i--) {
        for (int bit = 0; bit <= 7; bit++) {
            boolean isSet = ((bytes[i] >>> bit) & 1) == 1;
            if (isSet) {
                int shift = 8 * (bytes.length - 1 - i) + bit;
                int mask = 1 << shift;
                value |= mask;
            }
        }
    }
    return value;
}