在Java中如何将两个字节拼接起来?

4

我有一个名为writePos的整数,它取值范围在[0, 1023]之间。我需要将其存储在名为bucket的字节数组的最后两个字节中。因此,我认为我需要将其表示为数组的最后两个字节的连接。

  1. 我该如何将writePos拆分成两个字节,在将其串联并转换为int时,可以再次生成writePos

  2. 一旦我将其拆分为字节,我该如何进行连接?


为了什么目的?如果你正在处理I/O,可以看一下DataOutputStreamDataInputStream - user207421
我正在处理桶/缓冲区,并尝试记录桶中第一个可用的写入位置。桶的长度为1023位。因此,在我的字节数组(长度为1023,如我所提到的)的末尾有两个字节表示该索引的位置。 - AlwaysQuestioning
3个回答

2
位运算。
转为字节:
byte[] bytes = new byte[2];
// This uses a bitwise and (&) to take only the last 8 bits of i
byte[0] = (byte)(i & 0xff); 
// This uses a bitwise and (&) to take the 9th to 16th bits of i
// It then uses a right shift (>>)  then move them right 8 bits
byte[1] = (byte)((i & 0xff00) >> 8);from byte:

返回另一条路

// This just reverses the shift, no need for masking.
// The & here is used to handle complications coming from the sign bit that
// will otherwise be moved as the bytes are combined together and converted
// into an int
i = (byte[0] & 0xFF)+(byte[1] & 0xFF)<<8;

这里有一个可以供你测试的工作示例,演示了一些转换。链接地址:http://ideone.com/eRzsun。请随意尝试。

1
我不确定我完全明白正在发生什么。您能否用我的变量来解释一下这段代码的作用?我会尝试调试它。 - AlwaysQuestioning
@Brandon 现在看答案,添加了更多的解释。 - Tim B
byte[] bytes = new byte[2];byte[0] = (byte)i;byte[1] = (byte)(i >>> 8); 是可以的,因为从int到byte的赋值不会改变任何位。 - fredt
@fredt 是的,我更喜欢这样写作为答案,因为这样更清楚地表明了正在发生的事情。 - Tim B
当我这样做时,我得到了巨大的数字。只会越来越大。 - AlwaysQuestioning
显示剩余3条评论

2
这可以通过ByteBuffer进行高级处理。
short loc = (short) writeLocation;

byte[] bucket = ...
int idex = bucket.length - 2;
ByteBuffer buf = ByteBuffer.wrap(bucket);
buf.order(ByteOrder.LITTLE__ENDIAN); // Optional
buf.putShort(index, loc);

writeLocation = buf.getShort(index);

可以指定顺序,也可以使用默认值(BIG_ENDIAN)。

  1. ByteBuffer包装了原始的字节数组,并且对ByteBuffer的更改也会影响到字节数组。
  2. 可以使用顺序写入和读取以及定位(seek),但是这里我使用了重载方法来进行立即定位。
  3. putShort将两个字节(一个short)写入字节数组并进行修改。
  4. getShort从字节数组中读取一个short,该short可以放入int中。

说明

在Java中,short是一个两个字节(有符号)整数。这就是其含义。顺序是指LITTLE_ENDIAN:最低有效字节先(n % 256, n / 256)还是big endian。


我认为这是我需要的答案,因为我的项目正在使用bytebuffer。不过我不确定你的回答中发生了什么。这如何解释我的bucket中最后两个字节? - AlwaysQuestioning
添加了一段说明:Java中short被定义为2个字节,而不是int - Joop Eggen
这个有效了,谢谢。我希望能更好地理解正在发生的事情。似乎wrap函数为你提供的字节数组添加了功能,并实际修改了其内容。这是真的吗? - AlwaysQuestioning
1
你说得太对了,“wrap”意味着传递的数据,即字节数组,是字节缓冲区的后备存储。现在更清楚地提到了这一点。 - Joop Eggen

0
你需要把整数拆分成两个字节,高位字节和低位字节。根据你的描述,它以大端格式存储在数组中。
int writeLocation = 511;
byte[] bucket = new byte[10];
// range checks must be done before
// bitwise right rotation by 8 bits
bucket[8] = (byte) (writeLocation >> 8); // the high byte
bucket[9] = (byte) (writeLocation & 0xFF); // the low byte

System.out.println("bytes = " + Arrays.toString(bucket));

// convert back the integer value 511 from the two bytes
bucket[8] = 1;
bucket[9] = (byte) (0xFF);
// the high byte will bit bitwise left rotated
// the low byte will be converted into an int
// and only the last 8 bits will be added
writeLocation = (bucket[8] << 8) + (((int) bucket[9]) &  0xFF);
System.out.println("writeLocation = " + writeLocation);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接