我使用的协议要求以“网络字节顺序的4字节无符号整数”形式发送回文件中的当前位置。关于此有几个问题,但是它们假设我使用的是Integers,而不是Longs

我正在尝试将此端口移植到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中执行此操作的任何方法吗?希望以一种更明显的,自我描述的方式,然后上面的位转移魔术?

最佳答案

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

如果将long强制转换为int,则JVM会丢弃高位。将int提升为long时会出现问题:Java将对值进行符号扩展,用long的最高有效位填充int的高位。

要解决此问题,只需将遮罩长时间放置即可。以下内容应明确说明:

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)。

07-26 06:23
查看更多