2010-10-19 13 views
14

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.Java XML Parser para archivos enormes

¿Alguna sugerencia?

+0

1.8 gb es un archivo de texto ENORME. ¿No es posible descomponerlo en pedazos en el nivel de archivo? – Owen

+1

@Owen - Depende de su dominio. Al interactuar con los volcados de datos de los sistemas de otras personas, esta situación puede ocurrir muy fácilmente. –

+0

No pensé en eso, pero supongo que necesitamos de nuevo un analizador para evitar dañar el archivo xml. no será práctico hacer ese tipo de manual o cualquier sugerencia de cómo hacer eso? – mehmet6parmak

Respuesta

19

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).

+1

Aunque estoy de acuerdo en que StAX suele ser la mejor solución, hay situaciones en las que SAX es mejor. Si tiene documentos que contienen grandes bloques de contenido de texto, AFAIR the StAX API leerá esos bloques de texto en la memoria por completo y lo manejará como un solo evento. Los analizadores SAX normalmente lo dividirán en trozos más pequeños y lo alimentarán a sus manipuladores por partes. No se garantiza que aproveche esta oportunidad, pero en StAX esta oportunidad ni siquiera existe. (Lo que personalmente siento es un poco incómodo para una API de transmisión). –

+0

saludo, por favor alguien puede mejorar mi comprensión aquí. porque tuve una pregunta de la entrevista sobre esto y las palabras clave que contesté fueron 'sax' y' thread', pero aún así necesitaba la tercera palabra clave. Respondí el grupo de hilos del ejecutor ... dijo que sí y?! ~ la respuesta era prioridad. uno explica cómo – shareef

+0

@ wilfred-springer Coalesce es una característica que se puede configurar en XMLInputFactory - StAX API generalmente es compatible con esto de la misma manera que SAX. Ver por ejemplo, la fuente de entrada FasterXML. – ThomasRS

1

Use casi cualquier SAXParser para reproducir el archivo un poco a la vez.

3

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

SAX le proporciona un gran control y la gestión de eventos 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.

10

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

3

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

+0

¿Qué hay de la licencia que GPL? –

3

Como han dicho otros, utilice 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á haciendo spool en una base de datos, asegúrese de tener cuidado para que su proceso sea reiniciable o lo que sea. Pueden pasar muchas cosas en 1.8GB que pueden fallar en el medio.

4

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

+0

+10 para el útil tutorial –

0

+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 .

1

Tuve un problema similar: tuve que leer todo un archivo XML 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 tenía 4 GB y tenía una máquina de 8 GB, así que pensé que tal vez 3 GB del archivo eran 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 (la FS obviamente puede manejar la escritura secuencial de 3GB, y cuando la lea en el sistema operativo usará memoria disponible para una memoria caché del sistema de archivos ; aún podría haber 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 | Download 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