Java将4字节转换为int

Java将4字节转换为int,java,casting,packing,Java,Casting,Packing,我想知道这个文档中的解决方案是否仍然是解决方案,或者是否有其他方法从4字节中获取int 多谢各位 编辑:我从套接字获取字节[]。读取 编辑:int recvMsgSize=in.read(数据,0,缓冲区大小)如果recvMsgSize为-1,我知道连接已断开 当我使用DataInputStream而不是InputStream时,如何检测到这一点 谢谢 编辑:作为一名yoyo,为接受正确答案而道歉。但在mihi更新了最终响应后,该方法似乎是可靠的,并且减少了扩展编码,我认为这是最佳实践。取决于这

我想知道这个文档中的解决方案是否仍然是解决方案,或者是否有其他方法从4字节中获取int

多谢各位

编辑:我从套接字获取字节[]。读取

编辑:
int recvMsgSize=in.read(数据,0,缓冲区大小)如果recvMsgSize为-1,我知道连接已断开

当我使用DataInputStream而不是InputStream时,如何检测到这一点

谢谢


编辑:作为一名yoyo,为接受正确答案而道歉。但在mihi更新了最终响应后,该方法似乎是可靠的,并且减少了扩展编码,我认为这是最佳实践。

取决于这4个字节的来源:

当然,您仍然可以手动执行此操作,但在大多数情况下,使用其中之一(例如,如果您必须转换包含大量字节的字节数组,您可能希望在
ByteArrayInputStream
周围使用
DataInputStream
)更容易

编辑:如果需要更改尾数,则必须使用ByteBuffer,或自己反转字节,或自己进行转换,因为DataInput不支持更改尾数

Edit2:当您从套接字输入流获取它们时,我会将其包装成
DataInputStream
,并使用它读取各种数据。特别是因为InputStream.read(字节[])不能保证填充整个字节数组。。。DataInputStream.readFully执行此操作

DataInputStream in = new DataInputStream(socket.getInputStream());
byte aByte = in.readByte();
int anInt = in.readInt();
int anotherInt = in.readInt();
short andAShort = in.readShort(); // 11 bytes read :-)
byte[] lotOfBytes = new byte[anInt];
in.readFully(lotOfBytes);
Edit3:当从流中多次读取时,他们将继续读取您停止的位置,即。EaByte将是字节0,ANIT将是字节1到4,另一个将是字节5到8,等等。在所有这些之后,ReadFull将继续读取,并将阻塞,直到它读取了大量字节

当流停止(连接断开)时,您将得到
EOFException
而不是-1,因此如果您得到-1,int实际上是-1

如果您根本不想解析任何字节,可以跳过它们。DataInputStream不可能以两种不同的方式解析一个字节(即先从字节0到3读取一个int,然后从字节2到5读取一个int),但通常也不需要

例如:

// read messages (length + data) until the stream ends:
while (true) {
int messageLength;
try {
    messageLength = in.readInt(); // bytes 0 to 3
} catch (EOFException ex) {
    // connection dropped, so handle it, for example
    return;
}
byte[] message = new byte[messageLength];
in.readFully(message);
// do something with the message.
}
// all messages handled.

希望这能回答您的其他问题。

对于任何加宽转换和数字升级,您必须非常小心,但下面的代码将4
字节
转换为
int

    byte b1 = -1;
    byte b2 = -2;
    byte b3 = -3;
    byte b4 = -4;
    int i = ((0xFF & b1) << 24) | ((0xFF & b2) << 16) |
            ((0xFF & b3) << 8) | (0xFF & b4);
    System.out.println(Integer.toHexString(i)); // prints "fffefdfc"
字节b1=-1;
字节b2=-2;
字节b3=-3;
字节b4=-4;

inti=((0xFF&b1)正如mihi所说,这取决于从何处获取这些字节,但此代码可能有用:

int myNumber = (((int)byteOne) << 0) |
    (((int)byteTwo) << 8) |
    (((int)byteThree) << 16) |
    (((int)byteFour) << 24);

int-myNumber=((int)byteOne)功能风格的解决方案(仅用于多样性,使用起来不太方便):

private int addByte(int base,字节附录){

return(base如果它们已经存在于
字节[]
数组中,则可以使用:

int result = ByteBuffer.wrap(bytes).getInt();
或者,如果你的类路径上有谷歌,你有快捷方式:

int result = Ints.fromByteArray(array);

这样做的好处是,对于其他类型(long.fromByteArray
Shorts.fromByteArray
等)也有类似的优秀API.

虽然它看起来应该可以工作,但我们确定它在有符号位的情况下不会出错吗?我想你误解了。我希望4字节到int,而不是int到4字节。@ikurtz:已修复。抱歉误解。@Lo'oris:请随时检查最新版本。正是因为这个讨论,你才应该更好地使用pre-exis在ByteBuffer或DataInput中设置方法:-)它们确实有效。
(int)
是多余且错误的,您需要使用
&0xFF
掩码撤消符号扩展。这一个会弄乱符号位。PolyGene会赢。当您从套接字输入流中获取它们时,我会将其包装到DataInputStream中,并使用它读取所有类型的数据。特别是因为
InputStream.read(字节[])
不能保证读取整个字节数组…DataInputStream.readFully可以。可能重复[Convert 4 bytes to int]()@mihi:in.readFully(lotof bytes);这会在int消息长度头之后读取吗?它是从开始读取还是从4字节int数据保持器之后开始读取?好的,我正在学习:)@mihi:我如何使用DataInputStream处理关闭的/hungup连接?即-1?我是否执行readInt并得到-1?请建议.int recvMsgSize=in.readInt();(使用DataInputStream在术语或检测连接断开方面不起作用。请建议.int recvMsgSize=in.read());解决了。谢谢,你的帖子信息量最大。也谢谢其他人。位的偏移不是应该是8,不是4吗?
int result = Ints.fromByteArray(array);