将4字节转换为 int

我读取的二进制文件是这样的:

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


int a = // ???
}

我想做的是读取4个字节并从中创建一个 int 值,但是我不知道怎么做。

我觉得我必须一次抓取4个字节,然后执行一个“ byte”操作(比如 > > < < > & FF 之类的)来创建新的 int

这是什么成语?

剪辑

哎呀,这原来是有点更复杂(解释)

我试图做的是,读取一个文件(可能是 ascii,二进制,这并不重要) ,并提取它可能拥有的整数。

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

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010

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

11111111 11111111 11111111 11111111

应该是 -1

还有

01111111 11111111 11111111 11111111

就是 Integer.MAX_VALUE ( 2147483647 )

125488 次浏览

You should put it into a function like this:

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;
}

Example:

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

Output:

11111110111111001111100011110000

This takes care of running out of bytes and correctly handling negative byte values.

I'm unaware of a standard function for doing this.

Issues to consider:

  1. Endianness: different CPU architectures put the bytes that make up an int in different orders. Depending on how you come up with the byte array to begin with you may have to worry about this; and

  2. Buffering: if you grab 1024 bytes at a time and start a sequence at element 1022 you will hit the end of the buffer before you get 4 bytes. It's probably better to use some form of buffered input stream that does the buffered automatically so you can just use readByte() repeatedly and not worry about it otherwise;

  3. Trailing Buffer: the end of the input may be an uneven number of bytes (not a multiple of 4 specifically) depending on the source. But if you create the input to begin with and being a multiple of 4 is "guaranteed" (or at least a precondition) you may not need to concern yourself with it.

to further elaborate on the point of buffering, consider the BufferedInputStream:

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

Now you have an InputStream that automatically buffers 1024 bytes at a time, which is a lot less awkward to deal with. This way you can happily read 4 bytes at a time and not worry about too much I/O.

Secondly you can also use DataInputStream:

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

or even:

int i = in.readInt();

and not worry about constructing ints at all.

try something like this:

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

this is assuming that the lowest byte comes first. if the highest byte comes first you might have to swap the indices (go from 0 to 3).

basically for each byte you want to add, you first multiply a by 256 (which equals a shift to the left by 8 bits) and then add the new byte.

The easiest way is:

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

-- or --

DataInputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream("filename")));
int i = in.readInt();
for (int i = 0; i < buffer.length; i++)
{
a = (a << 8) | buffer[i];
if (i % 3 == 0)
{
//a is ready
a = 0;
}
}

ByteBuffer has this capability, and is able to work with both little and big endian integers.

Consider this example:


//  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());

Hope this helps.

just see how DataInputStream.readInt() is implemented;

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

If you have them already in a byte[] array, you can use:

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

source: here

You can also use BigInteger for variable length bytes. You can convert it to Long, Integer or Short, whichever suits your needs.

new BigInteger(bytes).intValue();

or to denote polarity:

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

For reading unsigned 4 bytes as integer we should use a long variable, because the sign bit is considered as part of the unsigned number.

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

This is tested well worked function

The following code reads 4 bytes from array (a byte[]) at position index and returns a int. I tried out most of the code from the other answers on Java 10 and some other variants I dreamed up.

This code used the least amount of CPU time but allocates a ByteBuffer until Java 10's JIT gets rid of the allocation.

int result;


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

This code is the best performing code that does not allocate anything. Unfortunately, it consumes 56% more CPU time compared to the above code.

int result;
short data0, data1, data2, data3;


data0  = (short) (array[index++] & 0x00FF);
data1  = (short) (array[index++] & 0x00FF);
data2  = (short) (array[index++] & 0x00FF);
data3  = (short) (array[index++] & 0x00FF);
result = (data0 << 24) | (data1 << 16) | (data2 << 8) | data3;

Converting a 4-byte array into integer:

//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) );

Here is a simple solution that works for me:

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

a is the least significant byte

b is the second least significant byte

c is the second most significant byte

and d is the most significant byte