2012-01-11 15 views
7

Tengo que leer un archivo de texto grande de, digamos, 25 GB y necesito procesar este archivo en 15-20 minutos. Este archivo tendrá múltiples secciones de encabezado y pie de página.Lectura y procesamiento de archivo de texto grande de 25GB

Intenté CSplit para dividir este archivo basado en el encabezado, pero está tardando alrededor de 24 a 25 minutos para dividirlo en varios archivos basados ​​en el encabezado, lo cual no es aceptable en absoluto.

Me trataron de lectura y escritura secuencial mediante el uso de BufferReader y BufferWiter junto con FileReader y FileWriter. Tarda más de 27 min. Nuevamente, no es aceptable.

Intenté otro enfoque como obtener el índice de inicio de cada encabezado y luego ejecutar varios subprocesos para leer el archivo desde una ubicación específica usando RandomAccessFile. Pero no hay suerte en esto.

¿Cómo puedo lograr mi requisito?

duplicado Posible de:

Read large files in Java

Respuesta

7

seleccione un valor de leer gran buffer (por ejemplo, 20 MB en lugar de 2 MB) para procesar los datos más rápido. Además, no use un BufferedReader debido a las bajas velocidades y las conversiones de caracteres.

Esta pregunta se ha hecho antes: Read large files in Java

0

Trate de usar java.nio para hacer un mejor uso de la funcionalidad de los sistemas operativos. Evite copiar los datos (por ejemplo, en una cadena), pero intente trabajar con offsets. Creo que las clases java.nio incluso tendrán métodos para transferir datos de un búfer a otro sin tener que pasar los datos a la capa java (al menos en Linux), pero eso se traducirá esencialmente en llamadas al sistema operativo.

Para muchos servidores web modernos, esta técnica ha sido clave para el rendimiento con el que pueden servir los datos estáticos: esencialmente delegan tanto como sea posible al sistema operativo para evitar duplicarlo en la memoria principal.

Permítanme enfatizar esto: simplemente buscar a través de un búfer de 25 GB es mucho más rápido que convertirlo en cadenas de Java (que puede requerir codificación/decodificación de conjuntos de caracteres y copia). Cualquier cosa que le ahorre copias y administración de la memoria lo ayudará.

+1

NIO tiene sus propios límites desagradables diseñados en el mismo: puede asignar 2 GB en el mejor de los casos como un búfer, ya que la API de búfer utiliza un int para todas las compensaciones. Esto hace que nio sea engorroso en el mejor de los casos para archivos grandes. – Durandal

5

Debe asegurarse de que el IO sea lo suficientemente rápido sin su procesamiento porque sospecho que el procesamiento, no el IO, le está ralentizando. Debería poder obtener 80 MB/s desde un disco duro y hasta 400 MB/s desde un disco SSD. Esto significa que puedes leer todo en un segundo.

Pruebe lo siguiente, que no es el más rápido, pero el más simple.

long start = System.nanoTime(); 
byte[] bytes = new byte[32*1024]; 
FileInputStream fis = new FileInputStream(fileName); 
int len; 
while((len = fis.read(bytes)) > 0); 
long time = System.nanoTime() - start; 
System.out.printf("Took %.3f seconds%n", time/1e9); 

A menos que encuentre que está obteniendo al mínimo 50 MB/s que tiene un problema de hardware.

0

Si la plataforma es correcta, es posible que desee desembolsar y llamar a una combinación de cat y sed. Si no es así, es posible que aún desee pagar y usar Perl a través de la línea de comandos. Para el caso que es absolutamente necesario que Java haga el procesamiento real, los otros han proporcionado suficientes respuestas.

Sin embargo, tenga en cuenta que bombardear no está exento de problemas. Pero perl o sed pueden ser las únicas herramientas ampliamente disponibles para rastrear y alterar 25 GB de texto en el marco de tiempo.

Cuestiones relacionadas