【发布时间】:2014-04-10 02:43:17
【问题描述】:
我有一个巨大的 XML 文件(15 GB)。我想将 XML 文件中的“文本”标签转换为单个页面。
示例 XML 文件:
<root>
<page>
<id> 1 </id>
<text>
.... 1000 to 50000 lines of text
</text>
</page>
... Like wise 2 Million `page` tags
</root>
我最初使用 DOM 解析器,但它会抛出 JAVA OUT OF MEMORY(Valid)。现在,我已经使用 STAX 编写了 JAVA 代码。它工作得很好,但性能真的很慢。
这是我写的代码:
XMLEventReader xMLEventReader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(filePath));
while(xMLEventReader.hasNext()){
xmlEvent = xMLEventReader.nextEvent();
switch(xmlEvent.getEventType()){
case XMLStreamConstants.START_ELEMENT:
if( element == "text")
isText = true;
break;
case XMLStreamConstants.CHARACTERS:
chars = (Characters) xmlEvent;
if(! (chars.isWhiteSpace() || chars.isIgnorableWhiteSpace()))
if(isText)
pageContent += chars.getData() + '\n';
break;
case XMLStreamConstants.END_ELEMENT:
String elementEnd = (((EndElement) xmlEvent).getName()).getLocalPart();
if( elementEnd == "text" )
{
createFile(id, pageContent);
pageContent = "";
isText = false;
}
break;
}
}
此代码运行良好。(忽略任何小错误)。据我了解, XMLStreamConstants.CHARACTERS 会为每一行文本标签进行迭代。如果 TEXT 标记中有 10000 行,则 XMLStreamConstants.CHARACTERS 将迭代接下来的 10000 行。有没有更好的方法来提高性能..?
【问题讨论】:
-
只是出于好奇,您目前需要多长时间才能加载和解析该文件?
-
我已经解析了 2GB 的文件。花了35分钟..
-
什么是
pageContent?是String吗?如果是这样,立即进行的一项简单优化是改用StringBuilder;它可以附加字符串,而不必像Strings+=那样制作字符串的全新副本(如果您知道开始的长度,您也可以使用初始保留容量构建它以减少内存重新分配和副本与)。 -
恐怕你主要受限于通过 2GB 文件所需的基本时间......我对 StAX 不够熟悉,但在 SAX 中的字符事件不是每行而是每个解析缓冲区中断,这可能是多行或一行的一部分,具体取决于行的长度以及文本内容开始时您碰巧在解析器的输入缓冲区中的位置。
-
为什么不使用可用的库来提取内容。 WikiXMLJ 是一个非常好的库 code.google.com/p/wikixmlj>