Szenario: Ich erhalte eine riesige XML-Datei über extrem langsames Netzwerk, also möchte ich so früh wie möglich die übermäßige Verarbeitung starten. Aus diesem Grund habe ich mich für SAXParser entschieden.Warum liest SAXParser so viel vor dem Werfen von Ereignissen?
Ich erwartete, dass nach einem Tag wird ein Ereignis erhalten.
Der folgende Test zeigt, was ich meine:
@Test
public void sax_parser_read_much_things_before_returning_events() throws Exception{
String xml = "<a>"
+ " <b>..</b>"
+ " <c>..</c>"
// much more ...
+ "</a>";
// wrapper to show what is read
InputStream is = new InputStream() {
InputStream is = new ByteArrayInputStream(xml.getBytes());
@Override
public int read() throws IOException {
int val = is.read();
System.out.print((char) val);
return val;
}
};
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, new DefaultHandler(){
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.print("\nHandler start: " + qName);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.print("\nHandler end: " + qName);
}
});
}
ich den Eingangsstrom eingewickelt, um zu sehen, was gelesen wird, und wenn die Ereignisse auftreten.
Was ich erwartet hatte so etwas wie das war:
<a> <- output from read()
Handler start: a
<b> <- output from read()
Handler start: b
</b> <- output from read()
Handler end: b
...
Leider wurde das Ergebnis folgendes:
<a> <b>..</b> <c>..</c></a> <- output from read()
Handler start: a
Handler start: b
Handler end: b
Handler start: c
Handler end: c
Handler end: a
Wo ist mein Fehler, und wie kann ich das erwartete Ergebnis zu bekommen?
Edit:
- Erste Sache ist, dass er versucht, die doc-Version zu erkennen, was alles scannen verursacht. Mit Doc-Version bricht er dazwischen (aber nicht wo ich es erwarte)
- Es ist nicht in Ordnung, dass er zum Beispiel 1000 Bytes lesen will und so lange blockiert, weil es möglich ist, dass der Stream nicht so viel enthält Zeitpunkt.
- fand ich die Puffergrößen in XMLEntityManager:
- public static final int DEFAULT_BUFFER_SIZE = 8192;
- public static endgültig int DEFAULT_XMLDECL_BUFFER_SIZE = 64;
- public static endgültig int DEFAULT_INTERNAL_BUFFER_SIZE = 1024;
Ich denke, Sie sollten versuchen, eine Bugger-Testdatei - Ich vermute, dass eine gepufferte Lese effektiv liest Ihre gesamte Datei vor der Verarbeitung, weil es die Datei in (sagen wir) 1k Chunks oder was auch immer - wenn Sie eine große Datei verwenden würde Sie können etwas mehr bekommen, als Sie erwarten. – Elemental