2013-01-14 25 views
1

我有一个字节数组(因为无符号字节不是一个选项),需要将其中的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中有更好的方法吗?

+0

棍棒和石头... – Bohemian

回答

11

你没有做到这一点,你可以使用一个ByteBuffer

int i = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN).getInt(); 

如果有许多整数读取,代码变为:

ByteBuffer buf = ByteBuffer.wrap(rdbuf).order(ByteOrder.LITTLE_ENDIAN); 

while (buf.remaining() >= 4) // at least four bytes 
    i = bb.getInt(); 

的Javadoc here。推荐用于需要处理二进制数据的任何情况(无论是读取还是写入数据)。可以做小端,大端,甚至本地排序。 (注意:默认情况下是大端)。

(编辑:@PeterLawrey正确地提到,这看起来像小端数据,固定的代码片段 - 也看到他对如何将文件中的内容直接包装成ByteBuffer答案)

注:

  • ByteOrder有一个名为.nativeOrder()的静态方法,它返回底层架构使用的字节顺序;
  • a ByteBuffer具有内建偏移;可以使用.position()查询当前的偏移量,并使用.position(int)进行修改; .remaining()将返回从当前偏移量中读取的剩余字节数,直到结束;
  • 有相对的方法会读取/写入缓冲区的当前偏移量和绝对方法,这些方法将从您指定的偏移量读取/写入。
+0

它在'java.nio' @steveh – Fildor

+1

+1的位数似乎是小端,所以你可能需要用'.order(的ByteOrder.LITTLE_ENDIAN).getInt();' –

+0

@PeterLawrey我太习惯于网络秩序:(感谢您注意我的错误 – fge

1

而不是读入一个字节[],你必须用一个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(); 
+0

@fge嗯,我错过了。谢谢你指出。 –

+0

看起来很有帮助,但我从文件中读取的数据是整数,短裤和字符串的混合,所以我必须根据具体情况处理每一位数据 – steveh

+0

哦,我明白了,您可以使用它来获取任意大小的对象,酷,这可能是一个更好的方式来做到这一点,谢谢 – steveh

相关问题