2010-05-24 106 views
8

首先,我在從數據庫獲取數據時遇到了問題,它佔用了太多內存並失敗了。我已經設置了-Xmx1500M,並且我正在使用滾動結果集,因此被照顧。現在我需要從數據中創建一個XML,但我不能將它放在一個文件中。目前,我這樣做:如何將大量數據從數據庫存儲到XML(內存問題)?

while(rs.next()){ 
       i++; 
       xmlStringBuilder.append("\n\t<row>"); 
       xmlStringBuilder.append("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>"); 
       xmlStringBuilder.append("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>"); 
       xmlStringBuilder.append("\n\t\t<IME_PJ>" + Util.transformToHTML(rs.getString("ime_pj")) + "</IME_PJ>"); 
//etc. 
       xmlStringBuilder.append("\n\t</row>"); 
       if (i%100000 == 0){ 
            //stores the data to a file with the name i.xml 
        storeKBR(xmlStringBuilder.toString(),i); 
        xmlStringBuilder= null; 
        xmlStringBuilder= new StringBuilder(); 
       } 

它的工作原理;我得到12個100 MB文件。現在,我想要做的是在一個文件中存儲所有這些數據(然後我壓縮),但是如果只刪除if部分,我就會失去內存。我想寫一個文件,關閉它,然後打開,但是這並沒有太大的幫助,因爲我打開文件時不得不將文件加載到內存中。

+0

這樣做的一種方法是 - 使用xml api寫入多個xml文件,然後使用文件i/o合併所有文件的內容? – Inv3r53 2010-05-24 08:11:17

回答

3

爲什麼不把所有數據寫入一個文件並用「append」選項打開文件?如果您只是要寫入文件,則無需讀取文件中的所有數據。

然而,這可能是一個更好的解決方案:

PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("data.xml"))); 

while(rs.next()){ 
    i++; 
    writer.print("\n\t<row>"); 
    writer.print("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>"); 
    writer.print("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>"); 
    writer.print("\n\t\t<IME_PJ>" + Util.transformToHTML(rs.getString("ime_pj")) + "</IME_PJ>"); 
    //... 

    writer.print("\n\t</row>"); 
} 

writer.close(); 

的的BufferedOutputStream將在打印之前,緩存中的數據,並且可以指定在構造函數中的緩衝區大小如果默認值不符合您的需求。詳情請參閱java API:http://java.sun.com/javase/6/docs/api/

+0

這聽起來不錯,但我不確定如何去做。這是我當前的代碼 fos = new FileOutputStream(new File(zipFolder + i +「.xml」)); fos.write(xmlString.getBytes()); fos.flush(); fos.close(); – Andrija 2010-05-24 07:25:17

+0

它仍然需要1.5 GB的RAM,但我可以處理很多:)謝謝 – Andrija 2010-05-24 08:10:15

+0

我很高興你能夠正常工作,但總的來說,沒有理由不能在64M的內存中完成這種任務:從數據庫流式傳輸結果是第一步(http://javaquirks.blogspot.com/2007/12/mysql-streaming-result-set.html),並將它們直接寫入文件是第二部分。 – 2010-05-24 09:20:28

3

您正在將完整的文件組裝到內存中:您應該做的是將數據直接寫入文件。

此外,您可能會考慮使用合適的XML API,而不是將XML組裝爲文本文件。一個簡短的教程可用here

0

好了,代碼重寫,我會包括整個操作:

//this is the calling/writing function; I have 8 types of "proizvod" which makes 
//8 XML files. After an XML file is created, it needs to be zipped by a custom zip class 
     generateXML(tmpParam,queryRBR,proizvod.getOznaka()); 
    writeToZip(proizvod.getOznaka()); 



//inside writeToZip 

    ZipEntry ze = new ZipEntry(oznaka + ".xml"); 
    FileOutputStream fos = new FileOutputStream(new File(zipFolder + oznaka + ".zip")); 
    ZipOutputStream zos = new ZipOutputStream(fos); 
    zos.putNextEntry(ze); 
    FileInputStream fis = new FileInputStream(new File(zipFolder + oznaka + ".xml")); 
    final byte[] buffer = new byte[1024]; 
    int n; 
    while ((n = fis.read(buffer)) != -1) 
     zos.write(buffer, 0, n); 
    zos.closeEntry(); 
    zos.flush(); 
    zos.close(); 
    fis.close(); 

// inside generateXML 
PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(zipFolder +oznaka + ".xml"))); 
     writer.print("\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); 
     writer.print("\n<PROSTORNE_JEDINICE>"); 
     stmt = cm.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
       ResultSet.CONCUR_READ_ONLY); 
     String q = ""; 
     rs = stmt.executeQuery(q); 
     if(rs != null){ 

      System.out.println("Početak u : " +Util.nowTime()); 
      while(rs.next()){ 
       writer.print("\n\t<row>"); 
       writer.print("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>"); 
       writer.print("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>"); 
       //etc 
       writer.print("\n\t</row>"); 
      } 
      System.out.println("Kraj u : " +Util.nowTime()); 
     } 
     writer.print("\n</PROSTORNE_JEDINICE>"); 

但generateXML部分仍然需要大量的內存(如果我猜正確的,它需要一點一點多,因爲它可以),我不知道我怎麼會優化它(使用替代提供writer.print函數的方法)?

相關問題