Java 将 4 个字节转换为 int
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2383265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert 4 bytes to int
提问by OscarRyz
I'm reading a binary file like this:
我正在读取这样的二进制文件:
InputStream in = new FileInputStream( file );
byte[] buffer = new byte[1024];
while( ( in.read(buffer ) > -1 ) {
int a = // ???
}
What I want to do it to read up to 4 bytes and create a int value from those but, I don't know how to do it.
我想做的是读取最多 4 个字节并从中创建一个 int 值,但是,我不知道该怎么做。
I kind of feel like I have to grab 4 bytes at a time, and perform one "byte" operation ( like >> << >> & FF and stuff like that ) to create the new int
我有点觉得我必须一次抓取 4 个字节,然后执行一个“字节”操作(比如 >> << >> & FF 和类似的东西)来创建新的 int
What's the idiom for this?
这个的成语是什么?
EDIT
编辑
Ooops this turn out to be a bit more complex ( to explain )
哎呀这结果有点复杂(解释)
What I'm trying to do is, read a file ( may be ascii, binary, it doesn't matter ) and extract the integers it may have.
我想要做的是,读取一个文件(可能是 ascii,二进制,没关系)并提取它可能具有的整数。
For instance suppose the binary content ( in base 2 ) :
例如,假设二进制内容(以 2 为基数):
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
The integer representation should be 1
, 2
right? :- / 1 for the first 32 bits, and 2 for the remaining 32 bits.
整数表示应该是1
,2
对吧?:- / 1 表示前 32 位,2 表示其余 32 位。
11111111 11111111 11111111 11111111
Would be -1
将是 -1
and
和
01111111 11111111 11111111 11111111
Would be Integer.MAX_VALUE ( 2147483647 )
将是 Integer.MAX_VALUE ( 2147483647 )
回答by cletus
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:
需要考虑的问题:
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
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;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.
Endianness:不同的 CPU 架构将组成 int 的字节放在不同的顺序中。根据您如何提出字节数组,您可能不得不担心这一点;和
缓冲:如果您一次抓取 1024 个字节并在元素 1022 处开始一个序列,您将在获得 4 个字节之前到达缓冲区的末尾。最好使用某种形式的缓冲输入流来自动进行缓冲,这样您就可以
readByte()
重复使用而不必担心它;Trailing Buffer:输入的末尾可能是奇数个字节(具体不是 4 的倍数),具体取决于来源。但是,如果您创建输入以开始并且“保证”为 4 的倍数(或至少是前提条件),您可能不需要担心它。
to further elaborate on the point of buffering, consider the BufferedInputStream
:
要进一步详细说明缓冲的要点,请考虑BufferedInputStream
:
InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);
Now you have an InputStream
that automaticallybuffers 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.
现在你有一个InputStream
是自动的时间,这是少了很多尴尬应对缓冲器1024个字节。这样你就可以愉快地一次读取 4 个字节,而不必担心过多的 I/O。
Secondly you can also use DataInputStream
:
其次,您还可以使用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 int
s at all.
并且根本不用担心构建int
s。
回答by stmax
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).
这是假设最低字节在前。如果最高字节首先出现,您可能需要交换索引(从 0 到 3)。
basically for each byte you want to add, you first multiply aby 256 (which equals a shift to the left by 8 bits) and then add the new byte.
基本上,对于要添加的每个字节,首先将a乘以256(等于向左移动 8 位),然后添加新字节。
回答by Taylor Leese
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();
回答by Andrey
for (int i = 0; i < buffer.length; i++)
{
a = (a << 8) | buffer[i];
if (i % 3 == 0)
{
//a is ready
a = 0;
}
}
回答by Tom
ByteBuffer has this capability, and is able to work with both little and big endian integers.
ByteBuffer 具有此功能,并且能够处理小端和大端整数。
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.
希望这可以帮助。
回答by Santhosh Kumar Tekuri
just see how DataInputStream.readInt() is implemented;
看看 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));
回答by iTEgg
回答by Jamel Toms
You can also use BigInteger for variable length bytes. You can convert it to Long, Integer or Short, whichever suits your needs.
您还可以将 BigInteger 用于可变长度字节。您可以根据需要将其转换为 Long、Integer 或 Short。
new BigInteger(bytes).intValue();
or to denote polarity:
或表示极性:
new BigInteger(1, bytes).intValue();
回答by Mounir
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.
要将无符号 4 字节作为整数读取,我们应该使用 long 变量,因为符号位被视为无符号数的一部分。
long result = (((bytes[0] << 8 & bytes[1]) << 8 & bytes[2]) << 8) & bytes[3];
result = result & 0xFFFFFFFF;
This is tested well worked function
这是测试良好的功能
回答by Nathan
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.
以下代码从array
(a byte[]
) 位置读取 4 个字节index
并返回 a int
。我尝试了 Java 10 的其他答案中的大部分代码以及我梦寐以求的其他一些变体。
This code used the least amount of CPU time but allocates a ByteBuffer
until Java 10's JIT gets rid of the allocation.
这段代码使用了最少的 CPU 时间,但分配了一个ByteBuffer
直到 Java 10 的 JIT 摆脱了分配。
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.
此代码是不分配任何内容的最佳性能代码。不幸的是,与上述代码相比,它多消耗了 56% 的 CPU 时间。
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;