我在接受采访时被问到这个问题。当然,解决方案有很多方法,但只是想知道是否有一些最好的方法脱颖而出。有一个2gb的巨大xml文件存储在具有512 mb RAM的低端PC的硬盘中。 xml文件存储时间戳和相应的字符串值。我必须设计一个工具来解析xml文件以获取特定信息,例如特定时间戳中的字符串。面试官并不关心工具中的搜索技术。他希望得到一个关于工具设计的高级方法,仅考虑512毫米RAM和仅2GB大小的工具。这有什么有趣的设计方法吗?
答案 0 :(得分:1)
也许解析应该用SAX而不是DOM完成。与DOM解析器一样,在访问数据之前,您可以在内存中获得完整的文档。如果我理解你是正确的,那么你已经知道你从一开始就感兴趣的时间戳,所以你可以使用SAX Parser来获得相应的字符串值,这应该更快,不应该消耗那么多的内存。
答案 1 :(得分:1)
XML解析有两种方法1)使用dom解析器2)使用sax解析器。尝试使用dom解析器解析具有512B RAM的2GB文件肯定会导致Out of Memory异常,因此,请使用sax解析器,因为您已经知道要查找的内容,所以它也会更快。
答案 2 :(得分:1)
对于此用例,我将使用Java SE 6中的 StAX API代替 SAX 。以下代码来自answer of mine to a similar question。 StAX用于将大型XML文件拆分为几个较小的文件:
import java.io.*;
import javax.xml.stream.*;
import javax.xml.transform.*;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
xsr.nextTag(); // Advance to statements element
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
File file = new File("out/" + xsr.getAttributeValue(null, "account") + ".xml");
t.transform(new StAXSource(xsr), new StreamResult(file));
}
}
}
下面是skaffman的类似答案,其中描述了如何使用StAX以块的形式处理XML文档。在他的回答中,JAXB用于处理块: