2010-05-24 15 views
8

सबसे पहले, मुझे डेटाबेस से डेटा प्राप्त करने में कोई समस्या थी, इसमें बहुत अधिक स्मृति और असफल रहा। मैंने -Xmx1500M सेट किया है और मैं स्क्रॉलिंग परिणाम का उपयोग कर रहा हूं ताकि इसका ख्याल रखा जा सके। अब मुझे डेटा से एक्सएमएल बनाना है, लेकिन मैं इसे एक फाइल में नहीं डाल सकता। फिलहाल, मैं इसे इस तरह कर रहा हूं:मैं डेटाबेस से बड़ी मात्रा में डेटा को एक्सएमएल (मेमोरी समस्या) में कैसे स्टोर कर सकता हूं?

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 एमबी फाइलें मिलती हैं। अब, मैं क्या करना चाहता हूं वह है कि वह डेटा एक फ़ाइल में है (जिसे मैं तब संपीड़ित करता हूं) लेकिन यदि केवल भाग को हटा दें, तो मैं स्मृति से बाहर हूं। मैंने एक फाइल को लिखने, इसे बंद करने, फिर खोलने की कोशिश करने के बारे में सोचा, लेकिन मुझे यह बहुत कुछ नहीं मिलेगा क्योंकि जब मैं इसे खोलता हूं तो मुझे फ़ाइल को स्मृति में लोड करना होगा।

+0

ऐसा करने का एक तरीका होगा - xml एपीआई का उपयोग करके एकाधिक एक्सएमएल फाइलों को लिखना और फिर फ़ाइल I/o का उपयोग कर सभी फाइलों की सामग्री मर्ज करें? – Inv3r53

उत्तर

3

क्यों एक फ़ाइल में सभी डेटा नहीं लिखते हैं और फ़ाइल "एपेंड" विकल्प के साथ खोलते हैं? फ़ाइल में सभी डेटा में पढ़ने की कोई आवश्यकता नहीं है यदि आप इसे लिखने जा रहे हैं।

बहरहाल, यह एक बेहतर समाधान हो सकता है:

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 यह मुद्रण से पहले डेटा बफ़र करेंगे, और अगर डिफ़ॉल्ट मान आपकी आवश्यकताओं के अनुरूप नहीं है कि आप निर्माता में बफर आकार निर्दिष्ट कर सकते हैं। विवरण के लिए जावा एपीआई देखें: http://java.sun.com/javase/6/docs/api/

+0

यह अच्छा लगता है लेकिन मुझे यकीन नहीं है कि यह कैसे करें। यह मेरा वर्तमान कोड fos = new FileOutputStream (नई फ़ाइल (ज़िपफ़ोल्डर + i + ".xml") है; fos.write (xmlString.getBytes()); fos.flush(); fos.close(); – Andrija

+0

यह अभी भी 1.5 जीबी रैम लेता है लेकिन मैं जितना अधिक संभाल सकता हूं :) धन्यवाद – Andrija

+0

मुझे खुशी है कि आपको यह काम मिल रहा है, लेकिन आम तौर पर, इस प्रकार का कार्य स्मृति के 64 एम में पूरा नहीं हो सका: स्ट्रीमिंग परिणाम डीबी पहला कदम है (http://javaquirks.blogspot.com/2007/12/mysql-streaming-result-set.html), और उन्हें सीधे फ़ाइल में लिखना दूसरा भाग है। –

3

आप स्मृति में पूरी फ़ाइल को जोड़ रहे हैं: आपको क्या करना चाहिए फ़ाइल को सीधे डेटा पर लिखना है।

इसके अतिरिक्त, आप XML फ़ाइल को टेक्स्ट फ़ाइल के रूप में एकत्र करने के बजाय उचित XML API का उपयोग करने पर विचार कर सकते हैं। एक संक्षिप्त ट्यूटोरियल here उपलब्ध है।

1

मुझे कभी भी इस उपयोगकेस का सामना नहीं हुआ है, लेकिन मुझे पूरा यकीन है कि vtd-xml xml के आकार का 1 जीबी से अधिक का समर्थन करता है। यह @http://vtd-xml.sourceforge.net

बाहर की जाँच के लायक है या फिर आप भी @http://www.ibm.com/developerworks/ "आउटपुट बड़े XML दस्तावेज़ों"

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 हिस्सा अभी भी स्मृति का एक बहुत लेता है (अगर मैं सही ढंग से अनुमान लगा रहा हूँ, यह के रूप में ज्यादा के रूप में यह कर सकते हैं थोड़ा करके बिट लेता है) और मैं नहीं दिख रहा है मैं इसे कैसे (एक वैकल्पिक का उपयोग का अनुकूलन कर सकता है लेखक.प्रिंट फ़ंक्शन को खिलाने का तरीका)?

संबंधित मुद्दे