1

我正在使用的协议要求将文件中的当前位置作为“网络字节顺序中的无符号 4 字节整数”发回。对此有几个问题,但他们假设我使用的是整数,而不是长整数

我正在尝试将其移植到 NIO 的 ByteBuffer 以便它可以在套接字通道中发送:

long bytesTransfered = ... some number of bytes transfered...
//TODO: What does this actually do?
outBuffer[0] = (byte) ((bytesTransfered >> 24) & 0xff);
outBuffer[1] = (byte) ((bytesTransfered >> 16) & 0xff);
outBuffer[2] = (byte) ((bytesTransfered >> 8) & 0xff);
//TODO: Why does netbeans say this does nothing?
outBuffer[3] = (byte) ((bytesTransfered >> 0) & 0xff);

他们在 ByteBuffer 中是否有任何方法可以做到这一点?希望以一种比上面的移位魔法更明显、更自我描述的方式?

4

2 回答 2

6

无论有符号还是无符号,位都是相同的。

如果将 a强制long转换为a int,JVM 会丢弃高位。将 an 提升int为 a时会出现问题long:Java 将对值进行符号扩展,longint.

要解决此问题,只需在 long 上应用蒙版即可。下面应该清楚地说明这一点:

long value = Integer.MAX_VALUE + 1234L;
System.out.println("original value    = " + value);

int iValue = (int)value;
System.out.println("value as int      = " + iValue);
byte[] array = new byte[4];

ByteBuffer buf = ByteBuffer.wrap(array);
buf.putInt(0, iValue);

int iRetrieved = buf.getInt(0);
System.out.println("int from buf      = " + iRetrieved);

long retrieved = iRetrieved;
System.out.println("converted to long = " + retrieved);

retrieved = retrieved & 0xFFFFFFFFL;
System.out.println("high bytes masked = " + retrieved);

但是,请注意,您仍然只有 32 位。如果文件大小大于 4Gb,您将无法将其放入 4 个字节(如果您必须担心文件 > 2G,那么您应该担心文件 > 4G)。

于 2013-05-22T19:46:32.300 回答
3

这正是ByteBuffer.putInt()它的用途。你说你正在使用long,但你也只想写四个字节,所以你必须把你longint. 否则使用putLong()并获得 8 个字节。

于 2013-05-22T01:46:45.970 回答