Java将4个字节转换为int

发布于 2024-09-01 15:14:02 字数 452 浏览 9 评论 0原文

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

谢谢。

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

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

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

谢谢。

编辑:对于接受正确答案作为溜溜球者表示歉意。但在 mihi 更新最终回复后,该方法似乎很可靠,并且减少了扩展编码,在我看来是最佳实践。

i was wondering if the solution for this documented here is still the solution or is there any other way getting an int from 4 bytes?

thank you.

EDIT: im getting the byte[] from sockets .read

EDIT: int recvMsgSize = in.read(Data, 0, BufferSize); if recvMsgSize is -1 i know the connection has been dropped.

how do i detect this when im using DataInputStream instead of InputStream?

thanks.

EDIT: apologies for being a yoyo regarding accepting the right answer. but after mihi's updated final response, it would appear that the method is solid and cuts down extended coding and in my opinion best practice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

别把无礼当个性 2024-09-08 15:14:02

您必须非常小心任何扩大转换和数字提升,但下面的代码将 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代码将字节转换为十六进制
    • 注意需要用&掩码0xFF - 如果您使用 byte,您可能最终会做很多这样的事情,因为所有算术运算都会提升为 int (或 int) >长)

You have to be very careful with any widening conversion and numeric promotion, but the code below converts 4 byte into 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"

See also

  • Java code To convert byte to Hexadecimal
    • Pay attention to the need to mask with & 0xFF -- you'll probably end up doing a lot of this if you're working with byte since all arithmetic operations promote to int (or long)
掀纱窥君容 2024-09-08 15:14:02

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

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

或者,如果您有 Google 的 guava-libraries 在你的类路径上,你有快捷方式:

int result = Ints.fromByteArray(array);

它的优点是你可以为其他类型提供同样好的 API(Longs.fromByteArrayShorts.fromByteArray 等)。

If you have them already in a byte[] array, you can use:

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

or, if you have Google's guava-libraries on your classpath, you have the shortcut:

int result = Ints.fromByteArray(array);

which has the advantage that you have similarly nice APIs for other types (Longs.fromByteArray, Shorts.fromByteArray, etc).

我很坚强 2024-09-08 15:14:02

取决于您从何处获取这 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,anInt将是字节5到8,等等。 readFully 将在所有这些之后继续读取,并会阻塞,直到读取完 lotOfbytes

当流停止(连接断开)时,您将得到 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.

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

Depending on where you get those 4 bytes from:

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)

You can of course still do it manually, but in most cases using one of those (if you have to convert a byte array with lots of bytes, you might want to use a DataInputStream around a ByteArrayInputStream for example) is easier.

Edit: If you need to change the endianness, you will have to use a ByteBuffer, or reverse the bytes yourself, or do the conversion yourself, as DataInput does not support changing the endianness.

Edit2: When you get them from the socket input stream, I'd wrap that one into a DataInputStream and use it for reading all kinds of data. Especially since InputStream.read(byte[]) will not guarantee to fill the whole byte array... DataInputStream.readFully does.

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: When reading multiple times from a stream, they will continue reading where you stopped, i. e. aByte will be byte 0, anInt will be bytes 1 to 4, anotherInt will be bytes 5 to 8, etc. readFully will read on after all that and will block until it has read lotOfbytes.

When the stream stops (the connection drops) you will get EOFException instead of -1, so if you get -1, the int really was -1.

If you do not want to parse any bytes at all, you can skip() them. Parsing one byte in 2 different ways is not possible with DataInputStream (i. e. read first an int from byte 0 to 3, then one from byte 2 to 5), but usually not needed either.

Example:

// 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.

Hope this answers your additional questions.

作死小能手 2024-09-08 15:14:02

功能风格的解决方案(只是为了多样性,恕我直言,使用起来不太方便):

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);
}

A solution in functional style (just for variety, imho not very convinient in use):

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);
}
本宫微胖 2024-09-08 15:14:02

正如 mihi 所说,这取决于您从哪里获取这些字节,但以下代码可能有用:

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

As mihi said, it depends on where you are getting those bytes from, but this code might be of use:

int myNumber = (((int)byteOne) << 0) |
    (((int)byteTwo) << 8) |
    (((int)byteThree) << 16) |
    (((int)byteFour) << 24);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文