本文使用Dom4J读取超大XML文件,并保持很小的内存占用量。适用于不需要将XML全部内容驻留在内存,处理一部分就扔掉一部分的情况。
需要注意的是应该在onStart方法里面将Element detach掉,还有就是除了注册需要的ElementHandler之外,还应该注册DefaultHandler,如例子中那样。
这是因为虽然已经用了SAX按流的方式读取XML文件,DOM4J还是会在内存创建XML的DOM结构,这会导致内存溢出,这时只要将Element对象Detach掉,在onEnd处理该Element之后,垃圾回收会将Detach的节点回收,这样就可以小内存占用处理大XML文件。
----
public class Dom4jSaxReaderSimpleExample implements ElementHandler {
public void start(File file) throws DocumentException {
SAXReader reader = new SAXReader();
reader.addHandler("/root/item", this);
reader.setDefaultHandler(new PruningElementHandler());
reader.read(file);
}
@Override
public void onStart(ElementPath elementPath) {
elementPath.getCurrent().detach();
}
@Override
public void onEnd(ElementPath elementPath) {
Element elm = elementPath.getCurrent();
// TODO process with elm
elm.detach();
elm = null;
}
public static void main(String[] args) throws DocumentException {
new Dom4jSaxReaderSimpleExample().start(new File("big.xml"));
}
}
class PruningElementHandler implements ElementHandler {
public final void onStart(ElementPath elementPath) {
elementPath.getCurrent().detach();
}
public void onEnd(ElementPath elementPath) {
Element elem = elementPath.getCurrent();
elem.detach();
elem = null;
}
}
需要注意的是应该在onStart方法里面将Element detach掉,还有就是除了注册需要的ElementHandler之外,还应该注册DefaultHandler,如例子中那样。
这是因为虽然已经用了SAX按流的方式读取XML文件,DOM4J还是会在内存创建XML的DOM结构,这会导致内存溢出,这时只要将Element对象Detach掉,在onEnd处理该Element之后,垃圾回收会将Detach的节点回收,这样就可以小内存占用处理大XML文件。
----