Streaming de archivos en Java

Actualmente estoy desarrollando una aplicación de gráficos 3D usandoJOGL (Enlace Java OpenGL). En resumen, tengo un gran archivo binario horizontal. Debido a su tamaño, tengo que transmitir fragmentos de terreno en tiempo de ejecución. Por lo tanto, vemos explícitamente la preocupación de acceso aleatorio. Ya he terminado la primera implementación (y sucia :)) (tal vez es multiproceso), donde estoy usando un enfoque tonto ... Aquí está la inicialización de la misma:

dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());

Y cuando necesito leer (transmitir) un fragmento especial (ya sé su "desplazamiento" en el archivo) estoy realizando lo siguiente (lástima de mí :)):

dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);

Dado que tenía poca experiencia, eso fue lo primero en lo que podía pensar :) Entonces, hasta ahora he leído 3 artículos útiles y bastante interesantes (le sugiero que los lea, tal vez si está interesado en este tema)

Búferes de bytes y memoria sin almacenamiento dinámico - El Sr. Gregory parece estar alfabetizado en Java NIO.

Consejo de Java: cómo leer archivos rápidamente [http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly] - Ese es un punto de referencia interesante.

Artículos: Ajuste del rendimiento de E / S de Java [http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/] - Recomendaciones simples de Sun, pero desplácese hacia abajo y eche un vistazo a la sección "Acceso aleatorio" allí; muestran una implementación simple de RandomAccessFile (RAF) con mejora de auto-almacenamiento en búfer.

Gregory proporciona varios archivos * .java al final de su artículo. Uno de ellos es una evaluación comparativa entre FileChannel + ByteBuffer + Mapping (FBM) y RAF. Él dice que notó una aceleración 4x al usar FBM en comparación con RAF. He ejecutado este punto de referencia en las siguientes condiciones:

El desplazamiento (por ejemplo, lugar de acceso) se genera aleatoriamente (en el ámbito del archivo, por ejemplo, 0 - file.length ());El tamaño del archivo es de 220 MB;1 000 000 de accesos (75% de lecturas y 25% de escrituras)

Los resultados fueron asombrosos:

~ 28 segundos para RAF!~ 0.2 segundos para FBM!

Sin embargo, su implementación de RAF en este punto de referencia no tiene auto-buffering (el tercer artículo habla sobre uno), así que supongo que es la llamada al método "RandomAccessFile.seek", que reduce el rendimiento tan duro.

Ok, ahora después de todas esas cosas que he aprendido, hay 1 pregunta y 1 dilema :)

Pregunta: Cuando estamos mapeando un archivo usando "FileChannel.map", ¿Java copia todo el contenido del archivo en MappedByteBuffer? ¿O simplemente lo emula? Si se copia, entonces usar el enfoque FBM no es adecuado para mi situación, ¿verdad?

Dilema: Depende de tus respuestas sobre la pregunta ...

Si el mapeo copia un archivo, entonces parece que solo tengo 2 posibles soluciones:RAF + auto-buffering (el del tercer artículo) ohacer uso de la posición en FileChannel (no con mapeo) ... ¿Cuál sería mejor?

Si la asignación no copia un archivo, entonces tengo 3 opciones: dos anteriores yFBM en sí.

Editar: Aquí hay una pregunta más. Algunos de ustedes dicen que la asignación no copia el archivo en MappedByteBuffer. Bien, entonces, ¿por qué no puedo asignar un archivo de 1GB? Recibo el mensaje "error al asignar"

P. S. Me gustaría recibir una respuesta completa con consejos, ya que no puedo encontrar información coherente sobre este tema en Internet.

Gracias :)

Respuestas a la pregunta(3)

Su respuesta a la pregunta