将4个字节转换为int

Osc*_*Ryz 69 java data-conversion

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

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

   int a = // ??? 
}
Run Code Online (Sandbox Code Playgroud)

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

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

这个成语是什么?

编辑

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

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

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

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
Run Code Online (Sandbox Code Playgroud)

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

11111111 11111111 11111111 11111111
Run Code Online (Sandbox Code Playgroud)

将是-1

01111111 11111111 11111111 11111111
Run Code Online (Sandbox Code Playgroud)

将会 Integer.MAX_VALUE ( 2147483647 )

Tom*_*Tom 70

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

希望这可以帮助.


iTE*_*Egg 32

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

int result = ByteBuffer.wrap(bytes).getInt();
Run Code Online (Sandbox Code Playgroud)

来源:这里


cle*_*tus 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;
}
Run Code Online (Sandbox Code Playgroud)

例:

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

输出:

11111110111111001111100011110000
Run Code Online (Sandbox Code Playgroud)

这样可以减少字节数并正确处理负字节值.

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

需要考虑的问题:

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

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

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

要进一步阐述缓冲点,请考虑BufferedInputStream:

InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);
Run Code Online (Sandbox Code Playgroud)

现在你有一个InputStream自动的时间,这是少了很多尴尬应对缓冲器1024个字节.这样,您可以一次愉快地读取4个字节,而不用担心I/O太多.

其次你也可以使用DataInputStream:

InputStream in = new DataInputStream(new BufferedInputStream(
                     new FileInputStream(file), 1024));
byte b = in.readByte();
Run Code Online (Sandbox Code Playgroud)

甚至:

int i = in.readInt();
Run Code Online (Sandbox Code Playgroud)

并且根本不担心构建ints.

  • 您的代码的一个主要问题 - java的字节类型是SIGNED,因此如果设置了任何字节的最高位,您的代码也将设置结果int中的所有高位.你需要在移位和oring之前屏蔽每个字节的高位,例如`(bytes [0]&0xff)| ((bytes [1]&0xff)<< 8)| ...` (3认同)

San*_*uri 15

看看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));
Run Code Online (Sandbox Code Playgroud)

  • 应该注意的是,这是针对big-endian有序字节的,其中支持很少只需要一点改变:return((ch4 << 24)+(ch3 << 16)+(ch2 << 8)+(ch1 << 0)); (7认同)

Tay*_*ese 5

最简单的方法是:

RandomAccessFile in = new RandomAccessFile("filename", "r"); 
int i = in.readInt();
Run Code Online (Sandbox Code Playgroud)

- 要么 -

DataInputStream in = new DataInputStream(new BufferedInputStream(
    new FileInputStream("filename"))); 
int i = in.readInt();
Run Code Online (Sandbox Code Playgroud)