2011-02-28 22 views
5

¿Cómo puedo leer un archivo en bytes en Java?¿Cómo puedo leer un archivo como bytes sin firmar en Java?

Es importante tener en cuenta que todos los bytes deben ser positivos, es decir, no se puede utilizar el rango negativo.

¿Se puede hacer esto en Java y, en caso afirmativo, cómo?

Necesito poder multiplicar el contenido de un archivo por una constante. Asumí que podía leer los bytes en un BigInteger y luego multiplicarlos, sin embargo, dado que algunos de los bytes son negativos, terminé con 12 13 15 -12 etc. y me quedé atascado.

Respuesta

15

Bueno, Java no tiene el concepto de bytes sin signo ... el tipo byte siempre está firmado, con valores de -128 a 127 inclusive. Sin embargo, esto interoperará muy bien con otros sistemas que han funcionado con valores sin signo, por ejemplo, el código C# escribiendo un byte de "255" producirá un archivo donde el mismo valor se lee como "-1" en Java. Solo ten cuidado, y estarás bien.

EDITAR: Puede convertir el byte con signo a int con sin signo valor muy fácilmente utilizando una máscara de bits. Por ejemplo:

byte b = -1; // Imagine this was read from the file 
int i = b & 0xff; 
System.out.println(i); // 255 

hacer todo su aritmética utilizando int, y luego se echaron de nuevo a byte cuando es necesario escribirlo de nuevo.

Generalmente lee datos binarios de archivos utilizando FileInputStream o posiblemente FileChannel.

Es difícil saber qué más está buscando en este momento ... si puede dar más detalles en su pregunta, es posible que podamos ayudarlo más.

+0

que necesito para ser capaz de multiplicar el contenido de un archivo por una constante. Asumía que podía leer los bytes en un BigInteger y luego multiplicarlos; sin embargo, como algunos de los bytes son negativos, terminé con 12 13 15 -12 etc. y me atasco. – tyr

+0

@tyr: Editando ... –

+0

Gracias, creo que puede funcionar de esa manera, :) – tyr

1

Si usa un número entero mayor internamente no es un problema, solo vaya con la solución fácil y agregue 128 a todos los enteros antes de multiplicarlos. En cambio -128 a 127, se obtiene 0 a 255. La suma no es difícil;)

Además, recuerde que las aritméticas y operadores bit a bit en Java sólo devuelve enteros, por lo que:

byte a = 0; 
byte b = 1; 

byte c = a | b; 

daría una error de tiempo de compilación ya que a | b devuelve un número entero. Tendría que a

byte c = (byte) a | b; 

así que yo sugeriría simplemente añadiendo 128 a todos sus números antes de que se multipliquen.

+1

Suponiendo que quiere convertir de dos complemento a sin firmar, eso no funcionará. Por ejemplo -1 + 128 es igual a 127 * no * 255, como debería ser. Además, volver a un byte cambiará cualquier valor fuera del rango de un byte. – someguy

1

que escribió en un comentario (por favor ponga tal información en la pregunta - hay un enlace de edición para esto):

que necesito para ser capaz de multiplicar el contenido de un archivo por una constante. Estaba asumiendo que puedo leer los bytes en un BigInteger y luego multiplicar, sin embargo, dado que algunos de los bytes son negativos estoy terminando con 12 13 15 -12 etc. y se queda atascado.

Si desea utilizar todo el archivo como un BigInteger, léalo en un byte [] y dele esta matriz (como un todo) al constructor BigInteger.

/** 
* reads a file and converts the content to a BigInteger. 
* @param f the file name. The content is interpreted as 
* big-endian base-256 number. 
* @param signed if true, interpret the file's content as two's complement 
*     representation of a signed number. 
*    if false, interpret the file's content as a unsigned 
*     (nonnegative) number. 
*/ 
public static BigInteger fileToBigInteger(File f, boolean signed) 
    throws IOException 
{ 
    byte[] array = new byte[file.length()]; 
    InputStream in = new FileInputStream(file); 
    int i = 0; int r; 
    while((r = in.read(array, i, array.length - i) > 0) { 
     i = i + r; 
    } 
    in.close(); 
    if(signed) { 
     return new BigInteger(array); 
    } 
    else { 
     return new BigInteger(1, array); 
    } 
} 

A continuación, puede multiplicar su BigInteger y guardar el resultado en un nuevo archivo (utilizando el método toByteArray()).

Por supuesto, esto depende del formato de su archivo - mi método asume que el archivo contiene el resultado del método toByteArray(), no en otro formato. Si tiene algún otro formato, agregue información sobre esto a su pregunta.

"Necesito poder multiplicar el contenido de un archivo por una constante". parece un objetivo bastante dudoso, ¿qué es lo que realmente quieres hacer?

0

Algunas pruebas revelaron que este devuelve los valores de byte sin signo en [0 ... 255] variar de uno en uno a partir del archivo:

Reader bytestream = new BufferedReader(new InputStreamReader(
     new FileInputStream(inputFileName), "ISO-8859-1")); 
int unsignedByte; 
while((unsignedByte = bytestream.read()) != -1){ 
    // do work 
} 

Parece que es el trabajo de todos los bytes en el rango, incluyendo aquellos que no hay caracteres definidos en ISO 8859-1.

2

Con el unsigned API in Java 8 tiene Byte.toUnsignedInt. Eso será mucho más limpio que lanzar y enmascarar manualmente.

Para convertir de nuevo a intbyte después de jugar con él, por supuesto, sólo se necesita un molde (byte)value

Cuestiones relacionadas