将4个字节转换为int

时间:2010-03-04 22:41:32

标签: java data-conversion

我正在读这样的二进制文件:

InputStream in = new FileInputStream( file );
byte[] buffer = new byte[1024];
while( ( in.read(buffer ) > -1 ) {

   int a = // ??? 
}

我想做什么来读取最多4个字节并从那些创建一个int值但是,我不知道该怎么做。

我觉得我必须一次抓取4个字节,并执行一个“字节”操作(如>><<>>& FF和类似的东西)来创建new int

这是什么成语?

修改

哎呀这个结果有点复杂(解释)

我要做的是,读取一个文件(可能是ascii,二进制,无所谓)并提取它可能具有的整数。

例如假设二进制内容(在基数2中):

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010

整数表示应为12对吗? : - 前1位为32位,其余32位为2位。

11111111 11111111 11111111 11111111

将是-1

01111111 11111111 11111111 11111111

将是Integer.MAX_VALUE ( 2147483647 )

12 个答案:

答案 0 :(得分:69)

ByteBuffer具有此功能,并且能够处理小端和大端整数。

考虑这个例子:


//  read the file into a byte array
File file = new File("file.bin");
FileInputStream fis = new FileInputStream(file);
byte [] arr = new byte[(int)file.length()];
fis.read(arr);

//  create a byte buffer and wrap the array
ByteBuffer bb = ByteBuffer.wrap(arr);

//  if the file uses little endian as apposed to network
//  (big endian, Java's native) format,
//  then set the byte order of the ByteBuffer
if(use_little_endian)
    bb.order(ByteOrder.LITTLE_ENDIAN);

//  read your integers using ByteBuffer's getInt().
//  four bytes converted into an integer!
System.out.println(bb.getInt());

希望这有帮助。

答案 1 :(得分:27)

你应该把它放到这样的函数中:

public static int toInt(byte[] bytes, int offset) {
  int ret = 0;
  for (int i=0; i<4 && i+offset<bytes.length; i++) {
    ret <<= 8;
    ret |= (int)bytes[i] & 0xFF;
  }
  return ret;
}

示例:

byte[] bytes = new byte[]{-2, -4, -8, -16};
System.out.println(Integer.toBinaryString(toInt(bytes, 0)));

输出:

11111110111111001111100011110000

这会耗尽字节数并正确处理负字节值。

我不知道这样做的标准功能。

需要考虑的问题:

  1. Endianness:不同的CPU架构将构成int的字节放在不同的顺序中。根据您开始使用字节数组的方式,您可能不得不担心这一点;以及

  2. 缓冲:如果你一次抓取1024个字节并在元素1022处开始一个序列,你将在获得4个字节之前到达缓冲区的末尾。最好使用某种形式的缓冲输入流自动缓冲,这样你就可以反复使用readByte()而不用担心;

  3. 尾随缓冲区:输入的结尾可能是不均匀的字节数(具体为4的倍数),具体取决于来源。但是如果你创建输入开始并且是4的倍数是“保证”(或至少是一个先决条件),你可能不需要关心它。

  4. 要进一步详细说明缓冲点,请考虑BufferedInputStream

    InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);
    

    现在你有一个InputStream自动一次缓冲1024个字节,处理起来就不那么尴尬了。通过这种方式,您可以愉快地一次读取4个字节,而不必担心I / O太多。

    其次,您也可以使用DataInputStream

    InputStream in = new DataInputStream(new BufferedInputStream(
                         new FileInputStream(file), 1024));
    byte b = in.readByte();
    

    甚至:

    int i = in.readInt();
    

    并且根本不担心构建int

答案 2 :(得分:27)

如果已将它们放在byte []数组中,则可以使用:

int result = ByteBuffer.wrap(bytes).getInt();

来源:here

答案 3 :(得分:14)

看看DataInputStream.readInt()是如何实现的;

    int ch1 = in.read();
    int ch2 = in.read();
    int ch3 = in.read();
    int ch4 = in.read();
    if ((ch1 | ch2 | ch3 | ch4) < 0)
        throw new EOFException();
    return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

答案 4 :(得分:5)

最简单的方法是:

RandomAccessFile in = new RandomAccessFile("filename", "r"); 
int i = in.readInt();

- 或 -

DataInputStream in = new DataInputStream(new BufferedInputStream(
    new FileInputStream("filename"))); 
int i = in.readInt();

答案 5 :(得分:4)

尝试这样的事情:

a = buffer[3];
a = a*256 + buffer[2];
a = a*256 + buffer[1];
a = a*256 + buffer[0];

这假设最低字节首先出现。如果最高字节首先出现,则可能需要交换索引(从0到3)。

基本上对于要添加的每个字节,首先将 a 乘以256(等于向左移位8位),然后添加新字节。

答案 6 :(得分:1)

for (int i = 0; i < buffer.length; i++)
{
   a = (a << 8) | buffer[i];
   if (i % 3 == 0)
   {
      //a is ready
      a = 0;
   }       
}

答案 7 :(得分:1)

您还可以将BigInteger用于可变长度字节。您可以将其转换为Long,Integer或Short,以满足您的需求。

new BigInteger(bytes).intValue();

或表示极性:

new BigInteger(1, bytes).intValue();

答案 8 :(得分:1)

这是一个对我有用的简单解决方案:

int value = (a&255)+((b&255)<<8)+((c&255)<<16)+((d&255)<<24);

a 是最低有效字节

b 是第二个最低有效字节

c 是第二个最重要的字节

d 是最高有效字节

答案 9 :(得分:0)

为了读取无符号的4个字节作为整数,我们应该使用一个长变量,因为符号位被认为是无符号数的一部分。

long result = (((bytes[0] << 8 & bytes[1]) << 8 & bytes[2]) << 8) & bytes[3]; 
result = result & 0xFFFFFFFF;

这是经过测试的良好功能

答案 10 :(得分:0)

以下代码从位置array的{​​{1}}(byte[])读取4个字节,并返回index。我从Java 10上的其他答案以及我梦dream以求的一些其他变体中试用了大部分代码。

这段代码使用了最少的CPU时间,但是分配了int,直到Java 10的JIT取消了分配。

ByteBuffer

此代码是性能最好的代码,不分配任何内容。不幸的是,与上面的代码相比,它消耗了56%的CPU时间。

int result;

result = ByteBuffer.
   wrap(array).
   getInt(index);

答案 11 :(得分:0)

将4字节数组转换为整数:

//Explictly declaring anInt=-4, byte-by-byte
byte[] anInt = {(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xfc}; // Equals -4
//And now you have a 4-byte array with an integer equaling -4...
//Converting back to integer from 4-bytes...
result = (int) ( anInt[0]<<24 | ( (anInt[1]<<24)>>>8 ) | ( (anInt[2]<<24)>>>16) | ( (anInt[3]<<24)>>>24) );