将 4 个字节转换为 int
我正在读取这样的二进制文件:
InputStream in = new FileInputStream( file );
byte[] buffer = new byte[1024];
while( ( in.read(buffer ) > -1 ) {
int a = // ???
}
我想要读取最多 4 个字节并从中创建一个 int 值,但是我不知道该怎么做。
我感觉我必须一次抓取 4 个字节,并执行一个“字节”操作(如 >> << >> & FF 之类的)来创建新的 int
什么是这个的习语?
编辑
哎呀,这变得有点复杂(解释一下)
我想做的是,读取一个文件(可能是ascii,二进制,没关系)并提取它可能有的整数。
例如,假设二进制内容(以 2 为基数):
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
整数表示形式应该是 1
、 2
对吗? :- / 1 表示前 32 位,2 表示其余 32 位。
11111111 11111111 11111111 11111111
将为 -1
且
01111111 11111111 11111111 11111111
为 Integer.MAX_VALUE ( 2147483647 )
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.
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
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.
For instance suppose the binary content ( in base 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.
11111111 11111111 11111111 11111111
Would be -1
and
01111111 11111111 11111111 11111111
Would be Integer.MAX_VALUE ( 2147483647 )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(12)
您应该将其放入这样的函数中:
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
这负责处理字节用完并正确处理负字节值。
我不知道执行此操作的标准函数。
需要考虑的问题:
字节顺序:不同的 CPU 架构以不同的顺序放置组成 int 的字节。根据您如何开始创建字节数组,您可能需要担心这一点;
- 缓冲:如果您一次抓取 1024 个字节并在元素 1022 处开始一个序列,您将在获得 4 个字节之前到达缓冲区的末尾。最好使用某种形式的缓冲输入流来自动缓冲,这样您就可以重复使用
readByte()
而不必担心它; 尾随缓冲区:输入的末尾可能是奇数个字节(具体不是 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
。
以下代码从 array
位置 index
处读取 4 个字节(byte[]
)并返回一个 int
。我尝试了 Java 10 其他答案中的大部分代码以及我想象的其他一些变体。
这段代码使用了最少的 CPU 时间,但分配了一个 ByteBuffer,直到 Java 10 的 JIT 摆脱了分配。
int result;
result = ByteBuffer.
wrap(array).
getInt(index);
此代码是性能最好的代码,不分配任何内容。不幸的是,与上面的代码相比,它多消耗了 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;
将 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) );
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
ByteBuffer 具有此功能,并且能够处理小端和大端整数。
考虑这个例子:
希望这有帮助。
ByteBuffer has this capability, and is able to work with both little and big endian integers.
Consider this example:
Hope this helps.