2013-10-23 50 views
1

我在arraylist中需要一些3000個元素,需要將這3000個元素寫入xml。 在eclipse中執行需要20分鐘的時間。 有沒有任何有效的方法來做到這一點? 或對我的代碼進行任何修改?將文本寫入XML需要很長時間--Java

在ArrayList中的元素都應該在今後的成長......

我的代碼片斷..

--------------------------------------------------- 
--------------------------------------------------- 
for(int i=0;i<candidates.size();i++)//Candidates is my arraylist 
      { 
       String text=candidates.get(i); 
       //System.out.println(text); 
       text=text+"\n"; 
       file= new File("./test.xml"); 
       WriteToXML wr= new WriteToXML(file,"fullname",text); 

      } 
------------------------------------------------------- 
------------------------------------------------------- 
//WritetoXML class constructor 
public WriteToXML(File xml,String tag,String data) 
{ 
    try { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setValidating(false); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.parse(new FileInputStream(new File(xml))); 
     Element element = doc.getDocumentElement(); 
     NodeList node1 = doc.getElementsByTagName(tag); 
     Element fn= (Element) node1.item(0); 
     Text text = doc.createTextNode(data); 
     fn.appendChild(text); 
     printtoXML(doc); 
    } catch (Exception e) { 
      System.out.println(e.getMessage()); 
      } 
} 
public static final void printtoXML(Document xml) throws Exception { 
    Transformer tf = TransformerFactory.newInstance().newTransformer(); 
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
    tf.setOutputProperty(OutputKeys.INDENT, "yes"); 
    StringWriter sw = new StringWriter(); 
    StreamResult result = new StreamResult(sw); 
    DOMSource source = new DOMSource(xml); 
    tf.transform(source, result); 
    String xmlString = sw.toString(); 
    File file= new File(xml); 
    FileWriter fw=new FileWriter(file,false); 
    BufferedWriter bw = new BufferedWriter(fw); 
    bw.write(xmlString); 
    bw.flush(); 
    bw.close(); 
} 
+0

http://docs.oracle.com/javase/tutorial/jaxp/sax/parsing.html –

+0

你的代碼太慢了,因爲你總是實例化每個方法調用的許多對象(File,FileWriter ....)到寫入xml文件。如果你在文件中寫入一次而不是3000次,我想它會快得多,因爲那麼你必須打開一次(關閉和寫入)而不是3000次。 – Akkusativobjekt

+0

你有其他建議嗎? – user2814979

回答

1

把for循環放在WriteToXML()裏面。

主要功能:

file= new File("./test.xml"); 
WriteToXML wr= new WriteToXML(file,"fullname",candidates) 

內WriteToXML

public WriteToXML(File xml,String tag,List candidates) 
{ 
    try { 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setValidating(false); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(new FileInputStream(new File(xml))); 
    Element element = doc.getDocumentElement(); 
    NodeList node1 = doc.getElementsByTagName(tag); 
    Element fn= (Element) node1.item(0); 
    for (int i=0;i<candidates.size();i++) { 
     Text text = doc.createTextNode(candidates.get(i)+"\n"); 
     fn.appendChild(text); 
    } 
    printtoXML(doc); 
    } catch (Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

這樣,你是不是重新解析XML所有的時間和它寫一次。

我試過做最小的改變。我不會建議在構造函數中這樣做 - 除非有充分理由這麼做。

+0

相應地修改了我的代碼。執行時間少於2分鐘。 – user2814979

1

使用SAX而不是DOMSAXDOM

2

現在你正在爲每個3000元的這樣做更有效:

  1. 打開文件
  2. 解析文檔中有
  3. 的元素添加到DOM結構
  4. 刷新到磁盤文件並關閉它

路faste r將只執行一次步驟1,2和4(循環前的1 & 2; 4循環之後),並對列表中的每個元素(在循環中)執行第3步。 只需編寫一個新方法,它將您的tag變量和Document實例添加到文檔中。

這裏真正很貴的是將Object結構多次轉換爲XML並返回。這有很大的開銷。 文件IO也會帶來很多開銷,但與DOM結構的多重創建和解析相比,這應該是很小的。

+0

感謝您的明確信息。 – user2814979

1

作爲@Masud建議,使用SAX沒有其他辦法。這裏有一個很好的例子Generating XML from an Arbitrary Data Structure

+0

這個建議是誤導性的。由於這裏的任務是從已經存在於內存中的對象(int,候選列表)編寫XML結構,所以DOM對此非常合適。SAX可能非常適合提取數據和減少內存消耗(在這種情況下不需要),但它不是每個XML性能問題的答案。 – Matthias

+0

我建議你應該記錄創建dom文檔,分析和寫入文件的每個任務的持續時間。這會給你一個想法,哪一個需要很長時間。另一件事你可以直接將StreamResult(File f)傳遞給變換器,這將減少執行中的一個步驟。 – user2880879