【发布时间】:2016-01-18 23:22:08
【问题描述】:
场景:我正在通过极慢的网络接收一个巨大的 xml 文件,所以我希望尽早开始过度处理。因此,我决定使用 SAXParser。
我希望在一个标签完成后我会得到一个事件。
以下测试说明了我的意思:
@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);
}
});
}
我包装了输入流以查看读取的内容以及事件发生的时间。
我的预期是这样的:
<a> <- output from read()
Handler start: a
<b> <- output from read()
Handler start: b
</b> <- output from read()
Handler end: b
...
不幸的是,结果如下:
<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
我的错误在哪里,我怎样才能得到预期的结果?
编辑:
- 第一件事是他试图检测文档版本,这会导致扫描所有内容。使用文档版本,他介于两者之间(但不是我期望的)
- 他“想要”读取例如 1000 个字节和块这么长时间是不行的,因为此时流可能不包含这么多。
- 我在 XMLEntityManager 中找到了缓冲区大小:
- public static final int DEFAULT_BUFFER_SIZE = 8192;
- public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64;
- public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024;
【问题讨论】:
-
我认为您应该尝试一个错误的测试文件-我怀疑缓冲读取在开始处理之前有效地读取了您的整个文件,因为它会以(例如)1k 块或其他方式缓冲文件-如果你使用一个大文件,你可能会得到更像你期望的东西。
标签: java xml stream sax saxparser