在Java中将字节数组转换为整数,反之亦然

时间:2011-10-01 08:15:30

标签: java types endianness

我想将一些数据存储到Java中的字节数组中。基本上只是每个数字最多可以占用2个字节的数字。

我想知道如何将整数转换为2字节长字节数组,反之亦然。我发现了很多解决方案谷歌搜索,但大多数都没有解释代码中发生了什么。有很多变化的东西,我真的不明白,所以我希望得到一个基本的解释。

8 个答案:

答案 0 :(得分:199)

使用java.nio命名空间中的类,尤其是ByteBuffer。它可以为你做所有的工作。

byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1

ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }

答案 1 :(得分:115)

byte[] toByteArray(int value) {
     return  ByteBuffer.allocate(4).putInt(value).array();
}

byte[] toByteArray(int value) {
    return new byte[] { 
        (byte)(value >> 24),
        (byte)(value >> 16),
        (byte)(value >> 8),
        (byte)value };
}

int fromByteArray(byte[] bytes) {
     return ByteBuffer.wrap(bytes).getInt();
}
// packing an array of 4 bytes to an int, big endian
int fromByteArray(byte[] bytes) {
     return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}

当将带符号的字节打包到int中时,每个字节都需要被屏蔽掉,因为它由于算术提升规则(在JLS,转换和促销中描述)而被符号扩展为32位(而不是零扩展)。

有一个有趣的谜题与约瑟夫·布洛赫和尼尔·盖弗特在Java Puzzlers(“每个字节中的一个大喜悦”)中所描述的相关。将字节值与int值进行比较时,将字节符号扩展为int,然后将此值与其他int进行比较

byte[] bytes = (…)
if (bytes[0] == 0xFF) {
   // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255
}

请注意,所有数字类型都是用Java签名的,但char是16位无符号整数类型。

答案 2 :(得分:46)

您还可以将BigInteger用于可变长度字节。您可以将其转换为long,int或short,以满足您的需求。

new BigInteger(bytes).intValue();

或表示极性:

new BigInteger(1, bytes).intValue();

只需返回字节:

new BigInteger(bytes).toByteArray()

答案 3 :(得分:5)

基本实现将是这样的:

public class Test {
    public static void main(String[] args) {
        int[] input = new int[] { 0x1234, 0x5678, 0x9abc };
        byte[] output = new byte[input.length * 2];

        for (int i = 0, j = 0; i < input.length; i++, j+=2) {
            output[j] = (byte)(input[i] & 0xff);
            output[j+1] = (byte)((input[i] >> 8) & 0xff);
        }

        for (int i = 0; i < output.length; i++)
            System.out.format("%02x\n",output[i]);
    }
}

为了理解这些内容,您可以阅读此WP文章:http://en.wikipedia.org/wiki/Endianness

上述源代码将输出34 12 78 56 bc 9a。前2个字节(34 12)代表第一个整数等。上面的源代码以小端格式编码整数。

答案 4 :(得分:1)

/** length should be less than 4 (for int) **/
public long byteToInt(byte[] bytes, int length) {
        int val = 0;
        if(length>4) throw new RuntimeException("Too big to fit in int");
        for (int i = 0; i < length; i++) {
            val=val<<8;
            val=val|(bytes[i] & 0xFF);
        }
        return val;
    }

答案 5 :(得分:0)

有人要求必须从位中读取数据,可以说您只能从3位中读取数据,但是需要带符号整数,然后使用以下代码:

data is of type: java.util.BitSet

new BigInteger(data.toByteArray).intValue() << 32 - 3 >> 32 - 3

幻数3可以替换为您使用的位数(不是字节)

答案 6 :(得分:0)

番石榴通常会满足您的需求。

要从字节数组转到整型:File[$old_launch_agent_path],doc here

要从int转换为字节数组:Ints.fromBytesArray,doc here

答案 7 :(得分:-5)

我认为这是投射到int的最佳模式

   public int ByteToint(Byte B){
        String comb;
        int out=0;
        comb=B+"";
        salida= Integer.parseInt(comb);
        out=out+128;
        return out;
    }

首先将字节转换为字符串

comb=B+"";

下一步是转换为int

out= Integer.parseInt(comb);

但是这个reasone的字节在-128到127的范围内,我认为最好使用rage 0到255而你只需要这样做:

out=out+256;