2010-09-29 18 views
7

Tengo un archivo que contiene aproximadamente 200,000 valores largos que quiero leer lo más rápido posible en un largo []. Es para una aplicación de Android; las llamadas de función son lentas (por lo que cualquier cosa que implique leer un largo a la vez con un bucle "for" será súper lento) y necesito cargar para ser rápido. ¿Qué puedo usar? Todo lo que veo parece leer solo bytes rápidamente.¿La forma más rápida de leer largo [] del archivo?

He usado ByteBuffer y FileChannel desde el paquete NIO anterior y esta parece ser una manera muy rápida de cargar matrices de valores desde archivos. Sin embargo, no puedo descifrar cómo usar esto para leer datos en un largo []. He intentado ajustar un long [] como LongBuffer, pero no veo ninguna forma de que pueda enviar datos desde un archivo a un LongBuffer.

Edición: Cualquiera que sea el método que utilice, necesito poder usar Arrays.binarySearch en la matriz long[] al final.

+0

No estoy seguro de cómo esto ayuda. No puedo ver cómo responden mi pregunta. – memcom

Respuesta

3

No hay manera de emitir a byte[] en un long[]. Sin embargo, puede intentar usar un FileChannel para leer el contenido en un ByteBuffer y luego obtener un LongBuffer a través del ByteBuffer.asLongBuffer desde el que puede obtener un long[] hasta .

También podría intentar FileChannel.map para obtener un MappedByteBuffer del archivo. Esto puede ser más rápido que pasar por FileChannel.read.

Si esto no funciona, usted podría tratar de usar un FileChannel para leer el contenido en un ByteBuffer y luego acceder a los long s dentro de él, usando ByteBuffer.getLong(index).


Una solución alternativa. (ningún método-llamadas en el bucle :-)

byte[] byteArray = new byte[longCount * 8]; 
FileInputStream fis = new FileInputStream("lotsoflongs"); 
fis.read(byteArray); 
fis.close(); 
for (int i = 0; i < longCount; i += 8) 
    longArray[i >> 3] = ((long) byteArray[0+i]  << 56) + 
         ((long)(byteArray[1+i] & 255) << 48) + 
         ((long)(byteArray[2+i] & 255) << 40) + 
         ((long)(byteArray[3+i] & 255) << 32) + 
         ((long)(byteArray[4+i] & 255) << 24) + 
           ((byteArray[5+i] & 255) << 16) + 
           ((byteArray[6+i] & 255) << 8) + 
           ((byteArray[7+i] & 255) << 0); 

he punto de referencia algunas soluciones ahora, y éste parece ser la forma más rápida de hacerlo. Además, tenga en cuenta que los bytes reales leídos en fis.read(byteArray) pueden ser menores que el tamaño real de byteArray. Por lo tanto, si esto debe hacerse correctamente, debe colocarlo en un ciclo que itere hasta que se hayan leído todos los bytes.

+0

Necesito poder usar el largo [] como un largo [] después de, por ejemplo, usándolo con Arrays.binarySearch – memcom

+0

¿Qué tal si implementamos una 'Lista' de longs, respaldados por una matriz de bytes, y usamos Collections.binarySearch? – aioobe

+0

No estoy seguro de lo que quieres decir con esto? ¿Cómo crearía un objeto de lista? – memcom

1

Pruebe usar DataInputStream. Como puede averiguar fácilmente la longitud del archivo, también sabe cuántos elementos contiene (tamaño de archivo/8 bytes).

DataInputStream dataStream = new DataInputStream(inputStream); 

long count = filesize/8; 
long[] longArray = new long[count]; 

for(int i=0;i<count;i++) 
    longArray[i] = dataStream.getLong(); 

Supongo que debería ser suficiente para hacerte una idea.

+0

El OP descartó leer uno por uno en un bucle for. – aioobe

+0

@aioobe: ¿Por qué no acaba de implementar su propia versión de binarySearch para un LongBuffer? Debería ser bastante fácil, y entonces has terminado. :-) – mreichelt

Cuestiones relacionadas