studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java data-conversion

java - programacion - Convierta 4 bytes a int



manual de programacion android pdf (9)

ByteBuffer tiene esta capacidad, y es capaz de trabajar con enteros pequeños y grandes endian.

Considera este ejemplo:

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

Espero que esto ayude.

Estoy leyendo un archivo binario como este:

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

Lo que quiero hacer es leer hasta 4 bytes y crear un valor int a partir de esos, pero no sé cómo hacerlo.

Siento como si tuviera que tomar 4 bytes a la vez, y realizar una operación de "byte" (como >> << >> y FF y cosas por el estilo) para crear la nueva int

¿Cuál es el modismo para esto?

EDITAR

Ooops esto resulta ser un poco más complejo (explicar)

Lo que trato de hacer es leer un archivo (puede ser ascii, binario, no importa) y extraer los enteros que pueda tener.

Por ejemplo, supongamos el contenido binario (en la base 2):

00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000010

La representación entera debe ser 1 , 2 ¿verdad? : - / 1 para los primeros 32 bits, y 2 para los 32 bits restantes.

11111111 11111111 11111111 11111111

Sería -1

y

01111111 11111111 11111111 11111111

Sería Integer.MAX_VALUE ( 2147483647 )


Deberías ponerlo en una función como esta:

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

Ejemplo:

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

Salida:

11111110111111001111100011110000

Esto se ocupa de quedarse sin bytes y manejar correctamente los valores de bytes negativos.

No conozco una función estándar para hacer esto.

Problemas a considerar:

  1. Endianness: diferentes arquitecturas de CPU ponen los bytes que componen un int en diferentes órdenes. Dependiendo de cómo se le ocurra la matriz de bytes para empezar, tal vez tenga que preocuparse por esto; y

  2. Almacenamiento en búfer: si toma 1024 bytes a la vez e inicia una secuencia en el elemento 1022, llegará al final del búfer antes de obtener 4 bytes. Probablemente sea mejor usar alguna forma de flujo de entrada almacenado que haga el buffer automáticamente para que pueda usar readByte() repetidamente y no preocuparse de lo contrario;

  3. Trailing Buffer: el final de la entrada puede ser un número impar de bytes (no un múltiplo de 4 específicamente) dependiendo de la fuente. Pero si creas la entrada para comenzar y ser un múltiplo de 4 está "garantizado" (o al menos una condición previa), es posible que no necesites preocuparte por ello.

para profundizar más en el punto de almacenamiento en búfer, considere el BufferedInputStream :

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

Ahora tiene un InputStream que almacena automáticamente 1024 bytes a la vez, lo cual es mucho menos complicado de manejar. De esta forma, puede leer 4 bytes a la vez y no preocuparse por demasiada E / S.

En segundo lugar, también puedes usar DataInputStream :

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

o incluso:

int i = in.readInt();

y no te preocupes por construir int s en absoluto.


La forma más fácil es:

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

- o -

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


Para leer 4 bytes sin signo como entero, deberíamos usar una variable larga, porque el bit de signo se considera como parte del número sin signo.

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

Esta es una función bien probada


Si ya los tiene en una matriz de bytes [], puede usar:

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

fuente: here


También puede usar BigInteger para bytes de longitud variable. Puede convertirlo en Largo, Entero o Corto, según sus necesidades.

new BigInteger(bytes).intValue();

o para denotar la polaridad:

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


intente algo como esto:

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

esto supone que el byte más bajo es lo primero. si el byte más alto aparece primero, es posible que deba cambiar los índices (pasar de 0 a 3).

Básicamente, para cada byte que quiera agregar, primero debe multiplicar a por 256 (lo que equivale a un desplazamiento a la izquierda de 8 bits) y luego agregar el nuevo byte.


solo vea cómo se implementa 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));


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