ProgramingTip

4 바이트를 int로 변환

bestdevel 2020. 11. 7. 10:19
반응형

4 바이트를 int로 변환


다음과 같은 바이너리 파일을 읽고 있습니다.

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

   int a = // ??? 
}

최대 4 개의 바이트를 생성하여 그로부터 값을 생성하기 위해 수행하고 싶은 작업이 어떻게 해야할지 모르겠습니다.

나는 한 번에 4 바이트를 잡아야하고 새로운 int를 만들기 위해 하나의 "바이트"연산 (>> << >> & FF 등)을 수행해야합니다.

이것에 대한 관용구는 무엇입니까?

편집하다

죄송합니다. 이것은 좀 더 복잡한 구성입니다.

내가하려는 의도 파일을 추출하는 것입니다.

예를 들어 바이너리 콘텐츠 (base 2)가 가정합니다.

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010

정수 표현은 1, 2맞 수상? :-/ 처음 32 비트의 경우 1, 나머지 32 비트의 경우 2.

11111111 11111111 11111111 11111111

-1이 될 것입니다.

01111111 11111111 11111111 11111111

될 것이다 Integer.MAX_VALUE ( 2147483647 )


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

도움이 되셨기를 바랍니다.


이미 바이트 [] 배열에있는 경우 다음을 사용할 수 있습니다.

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

출처 : 여기


다음과 같은 함수에 넣어야합니다.

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. 엔디안 : 다른 CPU 아키텍처는 int를 구성하는 바이트를 다른 순서로 배치합니다. 시작하는 바이트 배열을 어떻게 생각해 냈는지에 따라 이것에 대해 걱정해야 할 수도 있습니다.

  2. 버퍼링 : 한 번에 1024 바이트를 확보 한 요소 1022에서 시퀀스를 시작하면 4 바이트를 전에 버퍼 끝까지 도달합니다. 자동으로 버퍼링되는 어떤 형태의 버퍼링 된 입력 스트림을 사용하는 것이 더 낫기 때문에 readByte()반복적으로 사용할 수 있고 명명 걱정하지 않습니다.

  3. 후행 버퍼 : 입력의 끝은 소스에 따라 고르지 않은 바이트 수 (4의 배수가 아님) 일 수 있습니다. 처음 시작할 때 필요한 것이 "보장"(또는 최소한 전제에 대해)에 대해 걱정할 필요가 없습니다.

지점에 대해 버퍼링 더 자세히 설명하려면 다음을 고려하십시오 .BufferedInputStream

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

이제 한 번에 1024 바이트 InputStream자동으로 버퍼링 하는 을 사용 하므로 처리하기가 훨씬 덜 어색합니다. 이렇게하면 한 번에 4 바이트를 즐겁게 읽을 수 있고 너무 많은 I / O에 대해 걱정할 필요가 없습니다.

둘째로 다음을 사용할 수도 있습니다 .DataInputStream

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

또는 :

int i = in.readInt();

ints 구성에 전혀 걱정하지 않습니다 .


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

가장 쉬운 방법은 다음과 가능합니다.

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

-또는-

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

다음과 같이 시도하십시오.

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

이것은 가장 낮은 바이트가 먼저 오는 것입니다. 가장 높은 바이트가 먼저 오면 수준을 교체해야 할 수도 있습니다 (0에서 3으로 이동).

기본적으로 추가 할 각 바이트에 먼저 a 에 256 (왼쪽으로 8 비트 이동)을 곱한 다음 새 바이트를 추가합니다.


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

가변 길이 바이트에 BigInteger를 사용할 수도 있습니다. 필요에 따라 Long, Integer 또는 Short로 변환 할 수 있습니다.

new BigInteger(bytes).intValue();

또는 극성을 표시하려면 :

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

부호없는 4 바이트를 정수로 읽으려면 부호 비트가 부호없는 숫자의 일부로 간주되기 때문에 긴 변수를 사용해야합니다.

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

이것은 잘 작동하는 기능을 테스트했습니다.


다음 코드는 4 바이트를 읽고 array(A byte[]위치) index와 리턴을 int. Java 10에 대한 다른 답변의 대부분의 코드와 내가 꿈꾸던 다른 변형을 시도했습니다.

이 코드는 CPU 시간을 가장 적게 사용했지만 ByteBufferJava 10의 JIT가 할당을 제거 할 때까지 a를 할당합니다.

int result;

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

이 코드는 아무 것도 할당하지 않는 가장 성능이 좋은 코드입니다. 안타깝게도 위의 코드에 비해 CPU 시간이 56 % 더 많이 소모됩니다.

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

참고 URL : https://stackoverflow.com/questions/2383265/convert-4-bytes-to-int

반응형