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