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

我想用 Java 把一些数据存储到字节数组中。基本上就是每个数字占用2字节的数字。

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

363097 次浏览

一个基本的实现应该是这样的:

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

为了了解事情,你可以阅读这篇可湿性粉剂文章: http://en.wikipedia.org/wiki/Endianness

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

使用在 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 }
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, minimal parentheses
// operator precedence: <<, &, |
// when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right
int fromByteArray(byte[] bytes) {
return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}


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

在将带符号的字节打包成 int 时,需要屏蔽每个字节,因为根据算术提升规则(在 JLS、转换和提升中描述) ,每个字节的符号扩展为32位(而不是零扩展)。

Joshua Bloch 和 Neal Gafter 在 Java Puzzlers (“ A Big Delight in Every Byte”)中描述了与此相关的一个有趣的谜题。当将一个字节值与一个 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位无符号整数类型之外。

还可以对可变长度的字节使用 BigInteger。您可以将其转换为 long、 int 或 short,以满足您的需要为准。

new BigInteger(bytes).intValue();

或表示极性:

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

返回字节:

new BigInteger(bytes).toByteArray()

我认为这是转换为 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);

但是由于这个原因,byte 的怒气为 -128到127,我认为最好使用怒气0到255,你只需要这样做:

out=out+256;
/** 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;
}

有些人需要从比特中读取数据,比方说你只需要从3比特中读取数据,但是你需要有符号整数,然后使用以下方法:

data is of type: java.util.BitSet


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

神奇的数字 3可以替换为您正在使用的数字 位(非字节)

通常,番石榴有你需要的东西。

从字节数组到 int: Ints.fromBytesArray,doc 给你

从 int 到 byte array: Ints.toByteArray,doc 给你