2010-10-19 20 views
14

मुझे लगभग 1.8 जीबी फ़ाइल को पार्स करने के लिए एक एक्सएमएल पार्सर चाहिए।
तो पार्सर को सभी फाइलों को स्मृति में लोड नहीं करना चाहिए।विशाल फ़ाइलों के लिए जावा एक्सएमएल पार्सर

कोई सुझाव?

+0

1.8 जीबी एक बड़ी टेक्स्ट फ़ाइल है। क्या फ़ाइल स्तर पर इसे टुकड़ों में तोड़ना संभव नहीं है? – Owen

+1

@ ओवेन - यह आपके डोमेन पर निर्भर करता है। अन्य लोगों के सिस्टम से डेटा डंप के साथ इंटरफेसिंग करते समय, यह स्थिति बहुत आसानी से हो सकती है। –

+0

मैंने इसके बारे में नहीं सोचा लेकिन मुझे लगता है कि हमें xml फ़ाइल को खराब करने से बचने के लिए फिर से ऐसे पार्सर की आवश्यकता है? यह व्यावहारिक नहीं होगा कि मैन्युअल रूप से या कोई सुझाव यह कैसे करें? – mehmet6parmak

उत्तर

19

अनुशंसित SAX पार्सिंग के अलावा, आप जेडीके (पैकेज javax.xml.stream) में शामिल StAX API (एक SAX विकास का प्रकार) का उपयोग कर सकते हैं।

+1

हालांकि मैं मानता हूं कि StAX आमतौर पर सबसे अच्छा समाधान है, ऐसी स्थितियां हैं जिनमें SAX बेहतर है। यदि आपके पास ऐसे दस्तावेज़ हैं जिनमें टेक्स्ट सामग्री के बड़े ब्लॉक हैं, तो AFAIR StAX API टेक्स्ट के उन ब्लॉक को पूरी तरह मेमोरी में पढ़ेगा और इसे एक ही ईवेंट के रूप में संभालेगा। SAX पार्सर्स सामान्य रूप से इसे छोटे हिस्सों में विभाजित करेंगे और इसे आपके हैंडलर को टुकड़े टुकड़े में खिलाएंगे। इस अवसर का लाभ उठाने की गारंटी नहीं है, लेकिन StAX में यह अवसर भी मौजूद नहीं है। (जिसे मैं व्यक्तिगत रूप से महसूस करता हूं स्ट्रीमिंग एपीआई के लिए थोड़ा अजीब है।) –

+0

ग्रीटिंग किसी को भी मेरी समझ में सुधार कर सकते हैं। क्योंकि मेरे पास इस बारे में साक्षात्कार का सवाल था और मैंने जिन महत्वपूर्ण शब्दों का उत्तर दिया था वह 'sax' और' thread' था लेकिन फिर भी उन्हें तीसरे कुंजी शब्द की आवश्यकता थी, मैंने निष्पादक थ्रेड पूल का उत्तर दिया ... उन्होंने कहा हाँ और?! ~ उत्तर प्राथमिकता कतार कुछ था एक व्याख्या करता है कि कैसे – shareef

+0

@ wilfred-springer Coalesce एक सुविधा है जिसे XMLInputFactory पर सेट किया जा सकता है - StAX API आमतौर पर SAX के समान ही इसका समर्थन करता है। उदाहरण के लिए FasterXML इनपुट फैक्टरी देखें। उपयोगी ट्यूटोरियल के लिए – ThomasRS

1

फ़ाइल को थोड़ी देर में स्ट्रीम करने के लिए लगभग SAXParser का उपयोग करें।

3

फ़ाइल को एक SAX पार्सर में स्ट्रीम करें और इसे टुकड़ों में स्मृति में पढ़ें।

SAX आपको बहुत अधिक नियंत्रण देता है और घटना-संचालित होने का अर्थ समझ में आता है। एपीआई पकड़ने के लिए थोड़ा मुश्किल है, आपको कुछ चीजों पर ध्यान देना होगा जैसे अक्षर() विधि कहलाती है, लेकिन मूल विचार यह है कि आप एक सामग्री हैंडलर लिखते हैं जिसे प्रत्येक के प्रारंभ और अंत में बुलाया जाता है एक्सएमएल तत्व पढ़ा जाता है। तो आप दस्तावेज़ में मौजूदा xpath का ट्रैक रख सकते हैं, यह पहचान सकते हैं कि किन पथों में आप रुचि रखते हैं, और यह पता लगाएं कि कौन सा पथ उस खंड के अंत को चिह्नित करता है जिसे आप सहेजना चाहते हैं या बंद करना चाहते हैं या अन्यथा प्रक्रिया करना चाहते हैं।

10

एक SAX आधारित पार्सर का उपयोग करें जो आपको घटनाओं की धारा में दस्तावेज़ की सामग्री के साथ प्रस्तुत करता है।

3

VTD-XML आज़माएं। मैंने इसे अधिक प्रदर्शन करने वाला पाया है, और अधिक महत्वपूर्ण बात यह है कि SAX से उपयोग करना आसान है।

+0

किस जीपीएल को लाइसेंस देने के बारे में? –

3

जैसा कि अन्य ने कहा है, एक सैक्स पार्सर का उपयोग करें, क्योंकि यह एक स्ट्रीमिंग पार्सर है। विभिन्न घटनाओं का उपयोग करके, आप अपनी जानकारी को आवश्यकतानुसार निकालते हैं और फिर, फ्लाई स्टोर पर इसे कहीं और (डेटाबेस, दूसरी फ़ाइल, आप क्या हैं) स्टोर करते हैं।

यदि आप वास्तव में केवल एक मामूली सबसेट की आवश्यकता है, या आप फ़ाइल को सारांशित कर रहे हैं तो आप इसे स्मृति में भी संग्रहीत कर सकते हैं। पाठ्यक्रम के उपयोग के मामले पर निर्भर करता है।

यदि आप डीबी में स्पूल कर रहे हैं, तो सुनिश्चित करें कि आप अपनी प्रक्रिया को पुनरारंभ करने योग्य या कुछ भी करने के लिए कुछ ध्यान दें। 1.8 जीबी में बहुत कुछ हो सकता है जो बीच में असफल हो सकता है।

4

StAX एपीआई SAX की तुलना में से निपटने के लिए आसान है। यहां एक short tutorial

+0

+10 –

0

+1 StaX के लिए है। एसएक्स की तुलना में उपयोग करना आसान है क्योंकि आपको कॉलबैक लिखने की आवश्यकता नहीं है (आप अनिवार्य रूप से केवल तब तक सभी तत्वों पर लूप करें जब तक आप पूरा नहीं कर लेते) और इसमें (AFAIK) फाइलों के आकार के रूप में कोई सीमा नहीं है जो इसे संसाधित कर सकती है ।

1

मुझे एक ही समस्या थी - मुझे पूरी एक्सएमएल फ़ाइल पढ़नी पड़ी और स्मृति में डेटा संरचना बनाना पड़ा। इस डेटा संरचना पर (पूरी चीज को लोड किया जाना था) मुझे विभिन्न परिचालन करना पड़ा। बहुत सारे एक्सएमएल तत्वों में पाठ होता है (जिसे मुझे अपनी आउटपुट फ़ाइल में आउटपुट करना था, लेकिन एल्गोरिदम के लिए महत्वपूर्ण नहीं था)।

ठीक है, जैसा कि यहां बताया गया है, मैंने फ़ाइल का विश्लेषण करने और अपनी डेटा संरचना का निर्माण करने के लिए SAX का उपयोग किया था। मेरी फाइल 4 जीबी थी और मेरे पास 8 जीबी मशीन थी इसलिए मुझे लगता है कि फाइल का 3 जीबी सिर्फ टेक्स्ट था, और जावा। लैंग।स्ट्रिंग को शायद यूटीएफ -16 का उपयोग करके उन पाठों के लिए 6 जीबी की आवश्यकता होगी।

यदि JVM कंप्यूटर से भौतिक RAM की तुलना में अधिक स्थान लेता है, तो मशीन स्वैप हो जाएगी। एक निशान + स्वीप कचरा संग्रह करने के परिणामस्वरूप पृष्ठों को यादृच्छिक क्रम में उपयोग किया जा रहा है और वस्तुओं को एक ऑब्जेक्ट पूल से दूसरे स्थानांतरित करने के लिए भी स्थानांतरित किया जा रहा है, जो मूल रूप से मशीन को मारता है।

तो मैंने एक फ़ाइल में डिस्क पर अपने सभी तारों को लिखने का फैसला किया (एफएस स्पष्ट रूप से 3 जीबी के अनुक्रमिक-लेखन को ठीक से संभाल सकता है, और ओएस में इसे पढ़ने पर फ़ाइल-सिस्टम कैश के लिए उपलब्ध स्मृति का उपयोग किया जाएगा ; अभी भी यादृच्छिक-पहुंच पढ़ा जा सकता है लेकिन जावा में जीसी से कम)। मैंने एक छोटी सहायक कक्षा बनाई है जिसे डाउनलोड करने के लिए आपका स्वागत है यदि यह आपकी मदद करता है: StringsFile javadoc | Download ZIP

StringsFile file = new StringsFile(); 
StringInFile str = file.newString("abc");  // writes string to file 
System.out.println("str is: " + str.toString()); // fetches string from file 
संबंधित मुद्दे