我正在尝试使用StAX解析器读取XML文件,该解析器具有近180k行。 核心逻辑在数据结构中查找某些标记,属性和存储。 对于这种类型的大文件,StAX解析器需要花费大量时间。 没有任何核心逻辑需要将近15分钟,只需迭代while循环。
while (eventReader.hasNext()) { }
我在同一个文件上尝试了SAX解析器来读取标签。它非常快,几秒钟就完成了。
StAX解析器会出现什么问题。 请建议任何适用于大型文件的XML解析器,并在各自的内存和空间利用率方面表现良好。 ?
答案 0 :(得分:0)
调用hasNext()
将始终返回true,除非您已到达输入的末尾,并且您的代码不会更改输入中的位置,因为它从不读取任何数据。您需要在循环中调用next()
,然后最终hasNext()
将返回false。
按照现代标准,180k行不是一个大文件。
答案 1 :(得分:0)
坚持使用StAX解析器,因为SAX和Stax都遵循用于解析XML的Streaming编程模型我在这里运行了SAX和StAX的示例代码
SAX Parser: 总时间:10.73毫秒 最大记忆:1842688 分配内存:125952 自由记忆:107293
StAX Parser: 总时间:7.5毫秒 最大记忆:1842688 分配内存:125952 免费记忆:120611
StAX是一个PULL API,而SAX是一个PUSH API意味着在StAx Parser的情况下,客户端应用程序在需要与XML信息集交互时调用XML解析库上的方法 - 也就是说,客户端只获取(拉取)XML数据明确要求它。但是在SAX解析器的情况下,XML解析器在解析器遇到XML信息集中的元素时将XML数据发送(推送)到客户端 - 也就是说,解析器发送数据是否或者不是客户准备好在那时使用它。 StAX API可以读取和写入XML文档。使用SAX API,只能读取XML文件。
StAX代码:
public static void main(String[] args) throws FileNotFoundException, XMLStreamException {
XMLInputFactory xf=XMLInputFactory.newInstance();
XMLStreamReader xsr=xf.createXMLStreamReader(new InputStreamReader(new FileInputStream("C:\\Users\\RNayyar\\Desktop\\Context\\processedFiles\\post.xml")));
String startElement = null;
String endElement =null;
String elementTxt = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
while (xsr.hasNext()) {
int e = xsr.next();
if(e==XMLStreamConstants.START_ELEMENT){
//System.out.println("StartElement Name :" + xsr.getLocalName());
startElement = xsr.getLocalName();
}
if(e==XMLStreamConstants.END_ELEMENT){
//System.out.println("EndElement Name :" + xsr.getLocalName());
endElement = xsr.getLocalName();
if(startElement.equalsIgnoreCase(endElement))
System.out.println(" ElementName : "+ startElement + " ElementText : " + elementTxt);
}
if(e==XMLStreamConstants.CHARACTERS){
//System.out.println("Element TextValue :" + xsr.getText());
elementTxt = (xsr.getText().contains("\n")) ? "" : xsr.getText();
}
}
}