Estoy escribiendo un analizador SAX en Java para analizar un archivo XML de 2,5 GB de artículos de wikipedia. ¿Hay alguna manera de controlar el progreso del análisis en Java?Supervisión del progreso del analizador Java SAX
Respuesta
Utilice un javax.swing.ProgressMonitorInputStream.
Suponiendo que sepa cuántos artículos tiene, ¿no puede mantener un contador en el controlador? P.ej.
public void startElement (String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if(qName.equals("article")){
counter++
}
...
}
(no sé si se está analizando "artículo", es sólo un ejemplo)
Si no conoce el número del artículo de antemano, tendrá que contar primero . Luego puede imprimir el estado nb tags read/total nb of tags
, digamos cada 100 etiquetas (counter % 100 == 0
).
O incluso tenga otro subproceso que controle el progreso. En este caso, es posible que desee sincronizar el acceso al contador, pero no es necesario ya que no necesita ser realmente preciso.
Mis 2 centavos
Me di cuenta de eso, pero estaba buscando una forma de hacerlo sin tener que contar primero los artículos. Pensé que tal vez había una forma de averiguar la posición del analizador en el archivo, porque puedo obtener fácilmente el tamaño del archivo. – Danijel
Usted puede obtener una estimación de la línea/columna actual en el archivo reemplazando el método de setDocumentLocator
org.xml.sax.helpers.DefaultHandler/BaseHandler
. Se llama a este método con un objeto desde el que puede obtener una aproximación de la línea/columna actual cuando sea necesario.
Editar: Por lo que yo sé, no hay una forma estándar de obtener la posición absoluta. Sin embargo, estoy seguro de que algunas implementaciones de SAX ofrecen este tipo de información.
Cerrar, pero entonces tendría que saber el número de líneas en el archivo, ¿verdad? – Danijel
De hecho. Otra idea podría haber sido señalada por el enigmático EJP. Puede estimar el progreso, utilizando el avance en la secuencia de entrada. Sin embargo, este no es el progreso en el análisis sintáctico, debido a la posibilidad de almacenamiento en memoria intermedia y lookaheads. –
que haría uso de la posición de flujo de entrada. Cree su propia clase de flujo trivial que delegue/herede de la "real" y realice un seguimiento de los bytes leídos. Como dices, obtener el tamaño total del archivo es fácil. No me preocuparía el almacenamiento en búfer, la búsqueda anticipada, etc., para archivos grandes como estos es el de alimentación de pollo. Por otro lado, limitaría la posición a "99%".
Gracias a la sugerencia de EJP de ProgressMonitorInputStream
, al final extendí FilterInputStream
para que ChangeListener
se pueda utilizar para supervisar la ubicación de lectura actual en términos de bytes.
Con esto tiene un control más fino, por ejemplo, para mostrar barras de progreso múltiples para lectura paralela de archivos xml grandes. Que es exactamente lo que hice.
Por lo tanto, una versión simplificada de la corriente controlable:
/**
* A class that monitors the read progress of an input stream.
*
* @author Hermia Yeung "Sheepy"
* @since 2012-04-05 18:42
*/
public class MonitoredInputStream extends FilterInputStream {
private volatile long mark = 0;
private volatile long lastTriggeredLocation = 0;
private volatile long location = 0;
private final int threshold;
private final List<ChangeListener> listeners = new ArrayList<>(4);
/**
* Creates a MonitoredInputStream over an underlying input stream.
* @param in Underlying input stream, should be non-null because of no public setter
* @param threshold Min. position change (in byte) to trigger change event.
*/
public MonitoredInputStream(InputStream in, int threshold) {
super(in);
this.threshold = threshold;
}
/**
* Creates a MonitoredInputStream over an underlying input stream.
* Default threshold is 16KB, small threshold may impact performance impact on larger streams.
* @param in Underlying input stream, should be non-null because of no public setter
*/
public MonitoredInputStream(InputStream in) {
super(in);
this.threshold = 1024*16;
}
public void addChangeListener(ChangeListener l) { if (!listeners.contains(l)) listeners.add(l); }
public void removeChangeListener(ChangeListener l) { listeners.remove(l); }
public long getProgress() { return location; }
protected void triggerChanged(final long location) {
if (threshold > 0 && Math.abs(location-lastTriggeredLocation) < threshold) return;
lastTriggeredLocation = location;
if (listeners.size() <= 0) return;
try {
final ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener l : listeners) l.stateChanged(evt);
} catch (ConcurrentModificationException e) {
triggerChanged(location); // List changed? Let's re-try.
}
}
@Override public int read() throws IOException {
final int i = super.read();
if (i != -1) triggerChanged(location++);
return i;
}
@Override public int read(byte[] b, int off, int len) throws IOException {
final int i = super.read(b, off, len);
if (i > 0) triggerChanged(location += i);
return i;
}
@Override public long skip(long n) throws IOException {
final long i = super.skip(n);
if (i > 0) triggerChanged(location += i);
return i;
}
@Override public void mark(int readlimit) {
super.mark(readlimit);
mark = location;
}
@Override public void reset() throws IOException {
super.reset();
if (location != mark) triggerChanged(location = mark);
}
}
no sabe - o cuidado - lo grande que la corriente subyacente es, por lo que necesita para obtener de alguna otra forma, como por ejemplo de el archivo en sí
lo tanto, aquí va la ejemplos de uso simplificado:
try (
MonitoredInputStream mis = new MonitoredInputStream(new FileInputStream(file), 65536*4)
) {
// Setup max progress and listener to monitor read progress
progressBar.setMaxProgress((int) file.length()); // Swing thread or before display please
mis.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) {
SwingUtilities.invokeLater(new Runnable() { @Override public void run() {
progressBar.setProgress((int) mis.getProgress()); // Promise me you WILL use MVC instead of this anonymous class mess!
}});
}});
// Start parsing. Listener would call Swing event thread to do the update.
SAXParserFactory.newInstance().newSAXParser().parse(mis, this);
} catch (IOException | ParserConfigurationException | SAXException e) {
e.printStackTrace();
} finally {
progressBar.setVisible(false); // Again please call this in swing event thread
}
En mi caso los avances plantean muy bien de izquierda a derecha sin saltos anormales. Ajuste el umbral para un equilibrio óptimo entre el rendimiento y la capacidad de respuesta. Demasiado pequeño y la velocidad de lectura puede más que duplicar en dispositivos pequeños, demasiado grande y el progreso no sería fluido.
Espero que ayude. ¡Siéntete libre de editar si encontraste errores o errores tipográficos, o vota para enviarme algunos estímulos!: D
¡Excelente! Exactamente lo que estaba buscando, lo adaptaré, ¡gracias! :) – Matthieu
- 1. Supervisión del progreso de Rsync
- 2. Supervisión del progreso utilizando Apache Commons FTPClient
- 3. analizador SAX vs XMLPull analizador
- 4. Analizador ligero XML C++ SAX
- 5. Java. Analizador de Sax. ¿Cómo romper el análisis sintáctico manualmente?
- 6. java 7 preguntas de supervisión del directorio
- 7. Supervisión del tamaño del directorio de Windows
- 8. Java SAX plantea UnknownHostException
- 9. Analizando html con el analizador SAX
- 10. Cómo analizar XML utilizando el analizador SAX
- 11. Java SAX Parsing
- 12. Supervisión del portapapeles en Mac OS X | Java
- 13. JAVA SAX parser llamadas divididas a caracteres()
- 14. Diferencia entre el analizador XML SAX, el analizador de arrastre y el analizador DOM en Android
- 15. Ajuste de la codificación para el analizador SAX en Python
- 16. Analizador SGML en Java?
- 17. Medición y supervisión del rendimiento del servidor Node.JS
- 18. Supervisión del rendimiento: Ganglia frente a grafito
- 19. Supervisión del paquete exec unicorn_rails con bluepill
- 20. ¿Supervisión del rendimiento para ASP.NET MVC2?
- 21. una herramienta de supervisión del servicio web
- 22. La diferencia entre: analizador SAX, XPath, DOM, XMLPullParser
- 23. Barra de progreso progresiva de Java del problema EDT
- 24. Progreso del informe en Directory.GetFiles
- 25. Cálculo del porcentaje de progreso
- 26. fecha y la hora del Lenguaje Natural analizador para Java
- 27. SAX vs XmlTextReader - SAX en C#
- 28. Erlang OTP supervisión de Java aplicación
- 29. Uso de la implementación del analizador XML como servicio OSGi
- 30. ¿Algún analizador de haml del lado del cliente?
Creo que esto será lo suficientemente cerca. ¡Gracias! – Danijel
¿Podría una respuesta ser más simple que eso? :) – Matthieu