2011-05-20 8 views
10

Acabo de encontrar que no hay un método readUnsignedInt() en la clase RandomAccessFile. ¿Por qué? ¿Hay alguna solución alternativa para leer un int sin signo del archivo?¿Por qué no readUnsignedInt en la clase RandomAccessFile?

Editar:

quiero leer un entero sin signo de archivo y ponerlo en un largo espacio.

Edit2:

No se puede utilizar readLong(). leerá 8 bytes, no 4 bytes. los datos en el archivo tienen entradas sin firmar en un rango de 4 bytes.

Edit3:

respuesta encontrado aquí: http://www.petefreitag.com/item/183.cfm

Edit4:

¿qué tal si el archivo de datos es ascendente hacia la izquierda? Necesitamos intercambiar bits primero?

+3

Java no admite enteros sin signo. http://stackoverflow.com/questions/430346/why-doesnt-java-support-unsigned-ints – Swati

+1

@Swati: Bueno, podrían haberlo hecho con 'readUnsignedShort()' que lee 2 bytes y devuelve un int : Lee 4 bytes y devuelve un largo. – musiKk

+0

También podrían haber implementado unsigned int, pero ¿qué se puede hacer? – Swati

Respuesta

19

que lo haría es así:

long l = file.readInt() & 0xFFFFFFFFL; 

La operación de bit es necesaria porque el upcast extenderá un signo negativo.


Concerning the endianness. Según mi leal saber y entender, todas las E/S en Java se realizan a lo grande. Por supuesto, a menudo no importa (las matrices de bytes, la codificación UTF-8, etc. no se ven afectadas por la endiancia) pero sí muchos métodos de DataInput. Si tu número está almacenado en little endian, tienes que convertirlo tú mismo. La única instalación en Java estándar que conozco permite la configuración de endianness es ByteBuffer a través del método order(), pero luego abres la puerta de entrada a NIO y no tengo mucha experiencia con eso.

+1

+1 buena sugerencia! – aioobe

+1

Sí, es mejor solución :) –

+0

Tenga en cuenta que sin la "L" al final del 0xFFFFFFFF esta solución no funcionará, sin la L si su número es negativo, su duración también será negativa –

2

¿Porque no hay unsigned int type en java? ¿Por qué no readLong()? Puede leer Long y luego tomar los primeros 32 bits.

Editar Usted puede intentar

long value = Long.parseLong(Integer.toHexString(file.readInt()), 16); 
+0

* ¿Porque no hay unsigned int type en java? * Bueno, en realidad hay un 'readUnsignedByte' ... – aioobe

+0

Y luego usa' seek() 'para ir 4 bytes atrás porque' readLong() 'consume demasiados bytes? – musiKk

+0

@aioobe, sí, lo siento, no noté estos métodos. –

3

Editado para eliminar readLong():

Usted podría utilizar readFully(byte[] b, int off, int len) y luego convertir a Long con los métodos aquí: How to convert a byte array to its numeric value (Java)?

+1

Eso comerá demasiados bytes, ¿no? – aioobe

+0

Esto no ayudará si el número en el archivo tiene 4 bytes de longitud. 'readLong()' lee 8 bytes. – musiKk

+0

Es cierto que podría usar 'readFully()' y luego convertir. –

0

Dependiendo de lo que esté haciendo con el int, es posible que no necesite convertirlo en un largo. Solo necesita estar al tanto de las operaciones que está realizando. Después de todo, solo tiene 32 bits y puede tratarlo como firmado o sin firmar como lo desee.

Si desea jugar con ByteOrder, lo más simple puede ser utilizar ByteBuffer, que le permite establecer un orden de bytes. Si su archivo tiene menos de 2 GB, puede asignar el archivo completo a la memoria y acceder al ByteBuffer de forma aleatoria.

Cuestiones relacionadas