Java将4个字节转换为int

我想知道这里记录的解决方案是否仍然是解决方案,还是有其他方式从4个字节获取一个int?

谢谢。

编辑:我从套接字.read获取byte []

编辑: int recvMsgSize = in.read(Data, 0, BufferSize); 如果recvMsgSize为-1,我知道连接已被删除。

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

谢谢。

编辑:对于接受正确答案的yoyo道歉。 但是在mihi更新了最终响应之后,看起来该方法是可靠的并且减少了扩展编码,并且在我看来是最佳实践。

取决于您从哪里获得这4个字节:

http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readInt()

http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#getInt(int)

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

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

Edit2 :当你从套接字输入流中获取它们时,我将它包装到DataInputStream并用它来读取所有类型的数据。 特别是因为InputStream.read(byte [])不能保证填充整个字节数组… 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 :当从流中读取多次时,它们将继续读取你停止的位置,即aByte将是字节0,anInt将是字节1到4,anotherInt将是字节5到8,等等。之后readFully将继续阅读并将阻止它读取lotOfbytes

当流停止(连接丢失)时,你会得到EOFException而不是-1,所以如果你得到-1,那么int确实是-1。

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

例:

 // 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 byte转换为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" 

也可以看看

  • Java代码将字节转换为hex
    • 注意需要使用& 0xFF进行掩码 - 如果你正在使用byte你可能最终会做很多这样做,因为所有的算术运算都提升为int (或long

如果已将它们放在byte[]数组中,则可以使用:

 int result = ByteBuffer.wrap(bytes).getInt(); 

或者,如果您的类路径中有Google的guava库 ,则可以使用以下快捷方式:

 int result = Ints.fromByteArray(array); 

它的优点是你有其他类型的类似的好API( Longs.fromByteArrayShorts.fromByteArray等)。

function风格的解决方案(仅适用于各种各样,使用时不太方便):

 private int addByte (int base, byte appendix) { return (base << 4) + appendix; } public void test() { byte b1 = 5, b2 = 5, byte b3 = 0, b4 = 1; int result = addByte (addByte (addByte (addByte (0, b1), b2), b3), b4); } 

正如mihi所说,这取决于你从哪里得到这些字节,但这段代码可能有用:

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