我有一个字节数组(因为无符号字节不是一个选项),需要将其中的4个字节转换为32位int。我用这个:
byte rdbuf[] = new byte[fileLen+1];
int i = (rdbuf[i++]) | ((rdbuf[i++]<<8)&0xff00) | ((rdbuf[i++]<<16)&0xff0000) | ((rdbuf[i++]<<24)&0xff000000);
如果我不做所有的逻辑指针,它会扩展字节,这显然不是我想要的。
在c语言中,这是不需要动脑筋的。在Java中有更好的方法吗?
您不必这样做,您可以使用ByteBuffer
:
int i = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN).getInt();
如果有很多int型要读,代码变成:
ByteBuffer buf = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN);
while (buf.remaining() >= 4) // at least four bytes
i = bb.getInt();
Javadoc。建议在必须处理二进制数据的任何情况下使用(无论您是读取还是写入此类数据)。可以做小端序,大端序,甚至本地排序。(注意:默认为大端)。
(编辑:@PeterLawrey正确地提到,这看起来像小的端序数据,固定的代码提取-另外,参见他的回答如何将文件的内容直接包装成ByteBuffer
)
指出:
-
ByteOrder
有一个叫做.nativeOrder()
的静态方法,它返回底层架构使用的字节顺序; - a
ByteBuffer
有一个内置偏移量;当前偏移量可以用.position()
查询,用.position(int)
修改;.remaining()
将返回从当前偏移量到结束的剩余字节数; - 有相对方法,它将读取/写入缓冲区的当前偏移量,以及绝对方法,它将读取/写入您指定的偏移量。
你可以直接使用ByteBuffer来避免所有这些开销,而不是读入字节[],你必须用ByteBuffer来为你做移位/掩码。
FileChannel fc = new FileInputStream(filename).getChannel();
ByteBuffer bb = ByteBuffer.allocateDirect(fc.size()).order(ByteBuffer.nativeOrder());
fc.read(bb);
bb.flip();
while(bb.remaining() > 0) {
int n = bb.getInt(); // grab 32-bit from direct memory without shift/mask etc.
short s = bb.getShort(); // grab 16-bit from direct memory without shift/mask etc.
// get a String with an unsigned 16 bit length followed by ISO-8859-1 encoding.
int len = bb.getShort() & 0xFFFF;
StringBuilder sb = new StringBuilder(len);
for(int i=0;i<len;i++) sb.append((char) (bb.get() & 0xFF));
String text = sb.toString();
}
fc.close();