Java将4个字节转换为int

iTE*_*Egg 13 java casting packing

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

谢谢.

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

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

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

谢谢.

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

pol*_*nts 17

您必须非常小心任何扩展转换和数字促销,但下面的代码将4转换byteint:

    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"
Run Code Online (Sandbox Code Playgroud)

也可以看看

  • 我觉得你误解了.我想4个字节到int.不是int到4个字节. (2认同)
  • @Lo'oris:随时查看最新版本。 (2认同)

Cow*_*wan 17

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

int result = ByteBuffer.wrap(bytes).getInt();
Run Code Online (Sandbox Code Playgroud)

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

int result = Ints.fromByteArray(array);
Run Code Online (Sandbox Code Playgroud)

其中有你有其他类型的(同样漂亮的API的优势Longs.fromByteArray,Shorts.fromByteArray等等).


mih*_*ihi 8

取决于您从哪里获得这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)

当然你也可以手动仍然这样做,但在使用这些之一大多数情况下(如果你有一个字节数组转换有很多个字节的,你可能想使用一个DataInputStream围绕ByteArrayInputStream例如)更容易.

编辑:如果需要更改字节顺序,则必须使用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);
Run Code Online (Sandbox Code Playgroud)

Edit3:当从流中读取多次时,它们将继续读取你停止的位置,即aByte将是字节0,anInt将是字节1到4,anotherInt将是字节5到8,等等.之后readFully将继续读取并将阻止,直到它已阅读lotOfbytes.

当流停止(连接丢失)时,你将获得EOFException-1而不是-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.
Run Code Online (Sandbox Code Playgroud)

希望这能解答您的其他问题.