我想执行转换而不依赖于某些依赖于实现的技巧。有小费吗?
答案 0 :(得分:60)
您需要知道字节的字节顺序。
假设(如@ WhiteFang34)bytes
是长度为4的byte[]
,那么......
大端:
int x = java.nio.ByteBuffer.wrap(bytes).getInt();
小端:
int x = java.nio.ByteBuffer.wrap(bytes).order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt();
答案 1 :(得分:23)
假设bytes
是big-endian顺序的整数byte[4]
,通常用于网络:
int value = ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16)
| ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
& 0xFF
是必需的,因为byte
是用Java签名的,你需要在这里保留签名位。你可以用这个来反转这个过程:
bytes[0] = (byte) ((value >> 24) & 0xFF);
bytes[1] = (byte) ((value >> 16) & 0xFF);
bytes[2] = (byte) ((value >> 8) & 0xFF);
bytes[3] = (byte) (value & 0xFF);
答案 2 :(得分:6)
您需要指定数组的字节顺序,但假设bytes[0]
是最重要的字节,那么:
int res = ((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) |
((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);
此代码是100%可移植的,假设您首先使用反向算法创建字节数组。
字节顺序问题出现在您可以在本机整数类型和字节数组类型之间进行转换的语言中......然后发现不同的体系结构以不同的顺序存储整数的字节。
你不能用Java做那个演员。因此,对于Java到Java的通信,这应该不是问题。
但是,如果要向(例如)C或C ++中实现的某个远程应用程序发送或接收数据包,则需要“知道”网络数据包中使用的字节顺序。了解/解决这个问题的一些替代策略是:
根据上面的示例代码,每个人都使用“网络订单”(big-endian)来处理线路上的内容。 little-endian机器上的非java应用程序需要翻转字节。
发件人会在汇编数据时找出收件人所期望的订单并使用该订单。
接收方确定发送方使用的顺序(例如通过数据包中的标记)并进行相应的解码。
第一种方法是最简单和最广泛使用的,但如果发送方和接收方都是小端,它确实会导致2次不必要的字节序转换。
答案 3 :(得分:4)
不确定这是否是正确的java语法,但如何:
int value = 0;
for (i = 0; i <= 3; i++)
value = (value << 8) + (bytes[i] & 0xFF);
答案 4 :(得分:1)
假设你的字节[]来自某个地方,例如您可以使用的流
DataInputStream dis = ... // can wrap a new ByteArrayInputStream(bytes)
int num = dis.readInt(); // assume big-endian.
或
ByteChannel bc = ... // can be a SocketChannel
ByteBuffer bb = ByteBuffer.allocate(64*1024);
bc.read(bb);
bb.flip();
if (bb.remaining()<4) // not enough data
int num = bb.getInt();
发送数据时,您应该知道是否要发送big-endian或little endian。您必须假设其他事情,例如您是否发送4字节有符号整数。二进制协议充满了假设。 (这使它更紧凑,更快,但比文字更脆)
如果您不想做出尽可能多的假设,请发送短信。
答案 5 :(得分:1)
我们也可以使用以下来使其更加动态的字节数组大小 BigEndian格式:
public static int pareAsBigEndianByteArray(byte[] bytes) {
int factor = bytes.length - 1;
int result = 0;
for (int i = 0; i < bytes.length; i++) {
if (i == 0) {
result |= bytes[i] << (8 * factor--);
} else {
result |= bytes[i] << (8 * factor--);
}
}
return result;
}
Little Endian格式:
public static int pareAsLittleEndianByteArray(byte[] bytes) {
int result = 0;
for (int i = 0; i < bytes.length; i++) {
if (i == 0) {
result |= bytes[i] << (8 * i);
} else {
result |= bytes[i] << (8 * i);
}
}
return result;
}
这将有助于您将字节转换为int值
答案 6 :(得分:-2)
public static int toInt( byte[] bytes ) {
int result = 0;
for (int i=0; i<3; i++) {
result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
}
return result;
}