2009-04-23 31 views
7

Estoy interesado en analizar un archivo de texto bastante grande en Java (1.6.x) y me preguntaba qué enfoque (s) se consideraría una mejor práctica.Analizando archivos de texto grandes en tiempo real (Java)

El archivo probablemente tendrá aproximadamente 1Mb de tamaño y constará de miles de entradas en la línea de;

Entry 
{ 
    property1=value1 
    property2=value2 
    ... 
} 

etc.

Mi primer instinto es el uso de expresiones regulares, pero no tengo ninguna experiencia previa en el uso de Java en un entorno de producción, y así estoy seguro de lo poderoso que las clases son java.util.regex .

Para aclarar un poco, mi aplicación va a ser una aplicación web (JSP) que analiza el archivo en cuestión y muestra los diversos valores que recupera. Solo hay un archivo que se analiza (reside en un directorio de terceros en el host).

La aplicación tendrá un uso bastante bajo (tal vez solo un puñado de usuarios que la usen un par de veces al día), pero es vital que cuando la usen, la información se recupere lo más rápido posible.

Además, ¿hay alguna precaución que tomar al cargar el archivo en la memoria cada vez que se analiza?

¿Alguien puede recomendar un enfoque para tomar aquí?

Gracias

+2

¿Quiere decir en tiempo real o rápidamente? Los dos son muy diferentes. Realtime implica que usted devuelve una respuesta para cada entrada sin esperar más información. Esto a menudo es más lento que el procesamiento por lotes. –

+3

Además, 1 meg ya no se considera grande a menos que esté corriendo en una máquina con menos de 64 megas de memoria. –

+0

Quiero decir rápidamente: quiero que se envíe una solicitud desde la IU web al servidor, lo que indicará que debe analizar el archivo y devolver los resultados (en el tipo de estructura de datos que sea apropiado) y luego procesarlos para mostrarlos en la interfaz de usuario. –

Respuesta

8

Si va a ser de aproximadamente 1 MB y, literalmente, en el formato que indica, entonces parece que está sobreinnovando las cosas.

A menos que su servidor sea un ZX Spectrum o algo así, solo use expresiones regulares para analizarlo, golpee los datos en un mapa hash (y guárdelo allí), y no se preocupe. Tomará algunos megabytes en memoria, pero ¿y qué ...?

Actualización: Sólo para dar una idea concreta de actuación, algunas medidas que tomé de la performance of String.split() (que utiliza expresiones regulares) muestran que en una máquina de 2GHz, se necesita milisegundos para dividir 10.000 cadenas de 100 caracteres (en otras palabras, alrededor de 1 megabyte de datos, en realidad más cerca de 2MB en volumen puro de bytes, ya que las cadenas tienen 2 bytes por char). Obviamente, esa no es exactamente la operación que está realizando, pero entiende mi punto: las cosas no están tan mal ...

+0

Lo suficientemente justo, eso es realmente algo que me preguntaba también, si hubiera provocado este problema en mi cabeza. Creo que haré lo que diga y veré cómo me llevo. Si el rendimiento resulta ser un problema, entonces puedo volver y mirar las opciones sugeridas por otras respuestas. Saludos. –

+1

Honestamente, no creo que sea así - 1 MB no es realmente una gran cantidad de datos. –

5

Si se trata de una gramática correcta, utilice un generador de analizador como el GOLD Parsing System. Esto le permite especificar el formato y usar un analizador eficiente para obtener los tokens que necesita, obteniendo el manejo de errores casi de forma gratuita.

4

Me pregunto por qué esto no está en XML, y luego podría aprovechar las herramientas XML disponibles. Estoy pensando particularmente en SAX, en cuyo caso podrías analizar/procesar esto fácilmente sin tenerlo todo en la memoria.

¿Puedes convertir esto a XML?

Si no se puede, y se necesita un analizador, a continuación, echar un vistazo a JavaCC

+0

Es un archivo de registro de terceros, desafortunadamente no tengo control sobre el formato. –

3

Utilice la clase escáner y procesar el archivo de una línea a la vez. No estoy seguro de por qué mencionaste Regex. Regex casi nunca es la respuesta correcta a cualquier pregunta de análisis debido a la ambigüedad y la falta de contornos simmáticos sobre qué está sucediendo en qué contexto.

+0

Por favor, cuéntenos cómo las expresiones regulares son ambiguas. Sí, los diferentes sabores se comportan de manera diferente, pero son todos (más o menos) documentados y consistentes. Cada expresión, para un sabor dado, tiene un significado preciso e inequívoco. –

+0

Cuando se vuelven complicados (RegEx), no hacen lo que las personas creen que realmente están haciendo. Los problemas reales de análisis y sus soluciones nunca usan RegExs. ¿Hay algún compilador escrito con RegExs? –

+1

@ mP. Cuando las personas no tienden a entender algo claramente, a menudo lo llaman "EL AMBIGUO" ;; Solo deme un tiempo para entenderlo, esto reduce mucho el esfuerzo ... – KDjava

2

Puede usar el generador de analizador Antlr para crear un analizador capaz de analizar sus archivos.

1

No respondiendo a la pregunta sobre el análisis ... pero podría analizar los archivos y generar páginas estáticas tan pronto como lleguen nuevos archivos. Entonces no tendría problemas de rendimiento ... (Y creo que 1Mb no es un archivo grande, así que puede cargarlo en la memoria, siempre que no cargue demasiados archivos al mismo tiempo ...)

+0

Es el mismo archivo que se analiza todo el tiempo; editó la publicación para aclarar eso. –

1

Esto parece un formato de archivo bastante simple, por lo que puede considerar usar un Recursive Descent Parser. Comparado con JavaCC y Antlr, sus ventajas son que puede escribir algunos métodos simples, obtener la información que necesita y no necesita aprender un formalismo de generador de analizador. Sus contras pueden ser menos eficientes. Un analizador de descenso recursivo es, en principio, más fuerte que las expresiones regulares. Si puede encontrar una gramática para este tipo de archivo, le servirá para la solución que elija.

1

Si se trata de las limitaciones de las expresiones regulares de Java, no se preocupe . Suponiendo que sea razonablemente competente en la elaboración de expresiones regulares, el rendimiento no debería ser un problema. El conjunto de funciones también es muy rico, incluido mi favorito, possessive quantifiers.

1

la otra solución es hacer algún tipo de preprocesamiento (hecho fuera de línea, o como un trabajo cron) que produce una estructura de datos muy optimizada, que luego se utiliza para atender muchas solicitudes web (sin tener que volver a analizar el archivo) .

sin embargo, mirando el escenario en cuestión, eso no parece ser necesario.

Cuestiones relacionadas