我正在解析DatagramSocket中的无符号位。我总共有24位(或3个字节)进入 - 它们是:1个无符号8位整数,后跟16位有符号整数。但java永远不会将有符号的字节存储到字节/字节数组中?当java接收这些值时,你会丢失最后的第8位吗?
DatagramSocket serverSocket = new DatagramSocket(666);
byte[] receiveData = new byte[3]; <--Now at this moment I lost my 8th bit
System.out.println("Binary Server Listing on Port: "+port);
while (true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] bArray = receivePacket.getData();
byte b = bArray[0];
}
自从我把它变成一个字节后,我现在失去了第8位吗?是不是我初始化了一个3字节的字节数组?
答案 0 :(得分:12)
当java接收这些值时,你会丢失最后的第8位吗?
没有。在设置时,你最终会得到一个负值。
所以要获得0到255之间的值,最简单的方法是使用这样的东西:
int b = bArray[0] & 0xff;
首先byte
被提升为int
,它将对其进行签名扩展,如果原始值中的高位为1,则导致25个前导1位。 & 0xff
然后再次摆脱前24位:)
答案 1 :(得分:7)
不,你不会失去第8位。但不幸的是,Java有两个“功能”,这使得处理这些值更难以合理:
byte
读取到int
,就像这里的情况一样),“下”的符号位类型“已扩展。这意味着,例如,如果您读取字节0x80
,它将二进制转换为:
1000 0000
当你把它读成一个整数时,你得到:
1111 1111 1111 1111 1111 1111 1000 0000
^
This freaking bit gets expanded!
而你真的想要:
0000 0000 0000 0000 0000 0000 1000 0000
即整数值128.因此,您必须屏蔽它:
int b = array[0] & 0xff;
1111 1111 1111 1111 1111 1111 1000 0000 <-- byte read as an int, your original value of b
0000 0000 0000 0000 0000 0000 1111 1111 <-- mask (0xff)
--------------------------------------- <-- anded, give
0000 0000 0000 0000 0000 0000 1000 0000 <-- expected result
伤心,但确实如此。
更一般地说:如果您希望操作大量面向字节的数据,我建议您查看ByteBuffer,它可以提供很多帮助。但不幸的是,这不会让你无法进行位掩码操作,只是它可以更容易地读取给定数量的字节作为时间(作为基本类型)。
答案 2 :(得分:2)
在Java中,byte(以及short,int和long)只是签名的数字数据类型。但是,当将它们视为 unsigned 二进制数据时,这并不意味着任何数据丢失。如图所示,10000000
为-128
为带符号的十进制数。如果您正在处理二进制数据,只需将其视为二进制形式,您就可以了。