Java XML Parser para archivos enormes

Necesito un analizador xml para analizar un archivo de aproximadamente 1.8 gb.
Por lo tanto, el analizador no debe cargar todo el archivo en la memoria.

¿Alguna sugerencia?

Además del análisis SAX recomendado, puede usar la API StAX (una especie de evolución SAX), incluida en el JDK (paquete javax.xml.stream).

Use un analizador basado en SAX que le presente el contenido del documento en una secuencia de eventos.

StAX API es más fácil de tratar en comparación con SAX. Aquí hay un breve tutorial

Pruebe VTD-XML . Descubrí que es más eficiente y, lo que es más importante, más fácil de usar que SAX.

Como han dicho otros, use un analizador SAX, ya que es un analizador de transmisión. Usando los diversos eventos, extrae su información según sea necesario y luego, en el momento, la almacena en otro lugar (base de datos, otro archivo, lo que tiene).

Incluso puede almacenarlo en la memoria si realmente solo necesita un subconjunto menor, o si simplemente está resumiendo el archivo. Depende del caso de uso, por supuesto.

Si está cargando a un DB, asegúrese de tener cuidado de reiniciar su proceso o lo que sea. Pueden pasar muchas cosas en 1.8GB que pueden fallar en el medio.

Transmita el archivo en un analizador SAX y léalo en la memoria en fragmentos.

SAX te da mucho control y ser guiado por un evento tiene sentido. La API es un poco difícil de controlar, hay que prestar atención a algunas cosas como cuando se llama al método characters (), pero la idea básica es escribir un controlador de contenido al que se llama cuando el inicio y el final de cada uno El elemento xml es leído. De modo que puede realizar un seguimiento del xpath actual en el documento, identificar qué rutas tienen qué datos le interesan e identificar qué ruta marca el final de un fragmento que desea guardar o transferir o procesar de otro modo.

Use casi cualquier analizador SAX para transmitir el archivo un poco a la vez.

Tuve un problema similar: tuve que leer un archivo XML completo y crear una estructura de datos en la memoria. En esta estructura de datos (tenía que cargarse todo) tuve que hacer varias operaciones. Muchos de los elementos XML contenían texto (que tenía que mostrar en mi archivo de salida, pero no era importante para el algoritmo).

En primer lugar, como se sugiere aquí, utilicé SAX para analizar el archivo y crear mi estructura de datos. Mi archivo era de 4GB y tenía una máquina de 8GB, así que pensé que tal vez 3GB del archivo era solo texto, y java.lang.String probablemente necesitaría 6GB para esos textos usando su UTF-16.

Si la JVM ocupa más espacio que la computadora tiene RAM física, la máquina cambiará. Hacer una recolección de basura marca + barrido dará como resultado que se acceda a las páginas en orden aleatorio y también que los objetos se muevan de un grupo de objetos a otro, lo que básicamente destruye la máquina.

Así que decidí escribir todas mis cadenas en el disco en un archivo (obviamente, el FS puede manejar la escritura secuencial de 3 GB, y cuando lo lee en el sistema operativo usará la memoria disponible para un caché de sistema de archivos; tener lecturas de acceso aleatorio pero menos que un GC en Java). Creé una pequeña clase de ayuda que puede descargar si lo ayuda: StringsFile javadoc | Descargar ZIP .

 StringsFile file = new StringsFile(); StringInFile str = file.newString("abc"); // writes string to file System.out.println("str is: " + str.toString()); // fetches string from file 

+1 para StaX. Es más fácil de usar que SaX porque no necesita escribir devoluciones de llamada (básicamente solo pasa por todos los elementos del tiempo hasta que termina) y no tiene límite (AFAIK) en cuanto al tamaño de los archivos que puede procesar .