1

我有一个大约 400 MB 的 XML 文件我需要找到一个特定元素,然后将其日期属性从 mm-dd-yyyy 重新格式化为 dd-mm-yyyy 这是我正在使用的代码

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputXML);
doc.getDocumentElement().normalize();
//format the date 
    NodeList nodes = doc.getElementsByTagName("empDetails");
    for (int i = 0; i < nodes.getLength(); i++){
    String oldDate =nodes.item(i).getAttributes().getNamedItem("doj").getNodeValue();
    String newValue = //formatted to dd-mm-yyyy 
nodes.item(i).getAttributes().getNamedItem("doj").setTextContent(newValue);
}

    //now write back to file 
    // write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;        
transformer = transformerFactory.newTransformer();      
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(fileName));     
transformer.transform(source, result);      

然而,这在 Windows 32 位上内存不足 - 它失败了

所以我在一个unix盒子上尝试了这个并将内存设置为: java -Xmx3072m -classpath。我的测试

它确实运行了一段时间但再次失败

问题 - 是否可以处理我想要选择性更新和保存的 400 MB 文件?(我确信答案是肯定的)我的代码是不是坏的——我应该改变什么?(请不要将 unix shell 脚本作为替代解决方案 - 我的意图是使用 java)我应该进一步增加堆大小吗?谢谢,萨蒂什

4

1 回答 1

2

最好使用 StAX api 像流一样读取文档,同时写出(再次使用 StAX)您不想立即更改为临时文件的部分。当您到达您感兴趣的部分时,在将其反馈回临时文件之前更改值。完成后,您可以将临时文件重命名为旧文件。

我会推荐XMLEventReaderand XMLEventWriterXMLEvents你不关心你可以直接从读者传递到作者。这只会将您正在处理的文档的一小部分保留在内存中。

XMLEventReader reader = ...;
XMLEventWriter writer = ...;
XMLEvent cursor;

while(reader.hasNext()){
  cursor = reader.nextEvent();
  if(doICareAboutThisEvent(cursor)){
      writer.add(changeEvent(cursor));
  }else{
      writer.add(cursor);
  }

}

显然,实现可能会更复杂,并且您关于关注和编辑哪些元素的决定可能比单个元素的状态更复杂。这只是一个非常简单的例子。

于 2013-08-10T19:16:00.930 回答