Dom4j按流的方式读取超大文件

本文使用Dom4J读取超大XML文件,并保持很小的内存占用量。适用于不需要将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文件。

----

你可能感兴趣的:(xml)