2009-04-23 10 views
7

में बड़ी टेक्स्ट फ़ाइलों को पार्स करना मुझे जावा (1.6.x) में काफी बड़ी टेक्स्ट फ़ाइल को पार्स करने में दिलचस्पी है और यह सोच रहा था कि किस दृष्टिकोण (एस) को सर्वोत्तम अभ्यास माना जाएगा?रीयल-टाइम (जावा)

फ़ाइल शायद आकार में लगभग 1 एमबी होगी, और इसमें हजारों प्रविष्टियां होंगी;

Entry 
{ 
    property1=value1 
    property2=value2 
    ... 
} 

आदि

मेरी पहली वृत्ति रेगुलर एक्सप्रेशन का उपयोग करने के लिए है, लेकिन मैं एक उत्पादन वातावरण में जावा का उपयोग करने का कोई पूर्व अनुभव है, और इतने अनिश्चित कितना शक्तिशाली java.util.regex वर्ग हैं हूँ ।

थोड़ा सा स्पष्टीकरण के लिए, मेरा आवेदन एक वेब ऐप (जेएसपी) होने जा रहा है जो फ़ाइल को प्रश्न में पार्स करता है और इसे प्राप्त होने वाले विभिन्न मूल्यों को प्रदर्शित करता है। वहां केवल एक फ़ाइल है जो पार्स हो जाती है (यह मेजबान पर किसी तृतीय पक्ष निर्देशिका में रहता है)।

ऐप का काफी कम उपयोग होगा (शायद यह केवल कुछ मुट्ठी भर उपयोगकर्ताओं को दिन में दो बार उपयोग कर रहा है), लेकिन यह महत्वपूर्ण है कि जब वे इसका उपयोग करते हैं, तो जानकारी जितनी जल्दी हो सके पुनर्प्राप्त की जाती है।

इसके अलावा, क्या हर बार इसे पार्स किए जाने पर फ़ाइल को स्मृति में लोड करने के लिए कोई सावधानी बरतनी पड़ती है?

क्या कोई यहां लेने के लिए एक दृष्टिकोण की सिफारिश कर सकता है?

धन्यवाद

+2

क्या आपका मतलब रीयलटाइम या जल्दी है? दोनों बहुत अलग हैं। रीयलटाइम का तात्पर्य है कि आप अधिक इनपुट की प्रतीक्षा किए बिना प्रत्येक इनपुट के लिए उत्तर वापस देते हैं। यह अक्सर बैच प्रसंस्करण की तुलना में धीमी है। –

+3

इसके अलावा, 1 मेग अब तक बड़ा नहीं माना जाता है जब तक कि आप 64 मेगाहर्ट्ज से कम मेमोरी वाली मशीन पर चल रहे हों। –

+0

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

उत्तर

8

यदि यह आपके बारे में 1 एमबी और सचमुच प्रारूप में होगा, तो ऐसा लगता है कि आप चीजों को अतिरंजित कर रहे हैं।

जब तक आपका सर्वर एक ज़ेडएक्स स्पेक्ट्रम या कुछ नहीं है, तो बस इसे पार्स करने के लिए नियमित अभिव्यक्तियों का उपयोग करें, हैश मैप में डेटा डालें (और इसे वहां रखें), और इसके बारे में चिंता न करें। यह स्मृति में कुछ मेगाबाइट लेगा, लेकिन क्या ...?

अद्यतन: केवल आपके प्रदर्शन का एक ठोस जानकारी देने के लिए, कुछ माप मैं performance of String.split() के न लिया हो (नियमित अभिव्यक्ति का उपयोग करता है) पता चलता है कि एक 2GHz मशीन पर, यह मिलीसेकेंड 10,000 100-चरित्र तार विभाजित करने के लिए ले जाता है (दूसरे शब्दों में, लगभग 1 मेगाबाइट डेटा - वास्तव में बाइट्स की शुद्ध मात्रा में 2 एमबी के करीब है, क्योंकि स्ट्रिंग प्रति बाइट 2 बाइट हैं)। Obvioualy, यह काफी ऑपरेशन नहीं है जो आप कर रहे हैं, लेकिन आप मेरा मुद्दा प्राप्त करते हैं: चीजें खराब नहीं हैं ...

+0

पर्याप्त मेला - यह वास्तव में कुछ है जो मैं सोच रहा था - अगर मैंने अपने सिर में इस समस्या को अधिक से अधिक अंडा कर दिया था। मुझे लगता है कि मैं कहूंगा जैसा कि आप कहते हैं और देखें कि मैं कैसे चलता हूं। यदि प्रदर्शन एक मुद्दा साबित होता है तो मैं वापस आ सकता हूं और अन्य उत्तरों द्वारा सुझाए गए विकल्पों को देख सकता हूं। चीयर्स। –

+1

मैं ईमानदारी से नहीं सोचता कि यह होगा - 1 एमबी वास्तव में बहुत अधिक डेटा नहीं है। –

5

यदि यह एक उचित व्याकरण, एक पार्सर बिल्डर GOLD Parsing System रूप में इस तरह का उपयोग करें। यह आपको प्रारूप निर्दिष्ट करने और आपको आवश्यक टोकन प्राप्त करने के लिए एक कुशल पार्सर का उपयोग करने की अनुमति देता है, लगभग मुफ्त में त्रुटि-संचालन प्राप्त करता है।

4

मुझे आश्चर्य है कि यह एक्सएमएल में क्यों नहीं है, और फिर आप उपलब्ध एक्सएमएल टूलिंग का लाभ उठा सकते हैं। मैं विशेष रूप से सैक्स के बारे में सोच रहा हूं, इस मामले में आप आसानी से इसे स्मृति में रखे बिना आसानी से पार्स/संसाधित कर सकते हैं।

तो क्या आप इसे एक्सएमएल में बदल सकते हैं?

आप नहीं कर सकते हैं

, और आप एक पार्सर की जरूरत है, तो स्कैनर वर्ग का उपयोग करें और अपनी फ़ाइल एक समय में एक लाइन की प्रक्रिया JavaCC

+0

यह एक तृतीय पक्ष लॉग फ़ाइल है, दुर्भाग्यवश प्रारूप पर मेरा कोई नियंत्रण नहीं है। –

3

पर एक नज़र डालें। मुझे यकीन नहीं है कि आपने रेगेक्स का उल्लेख क्यों किया। Regex किसी भी पार्सिंग प्रश्न का लगभग सही जवाब कभी नहीं है क्योंकि अस्पष्टता और किस संदर्भ में क्या हो रहा है पर प्रतीकात्मक contorl की कमी के कारण।

+0

कृपया हमें बताएं कि नियमित अभिव्यक्ति कैसे अस्पष्ट हैं। हां, अलग-अलग स्वाद अलग-अलग व्यवहार करते हैं, लेकिन वे सभी (अधिक या कम) दस्तावेज और सुसंगत हैं। प्रत्येक अभिव्यक्ति, किसी दिए गए स्वाद के लिए, एक सटीक और स्पष्ट अर्थ है। –

+0

जब वे (RegEx) जटिल हो जाते हैं तो वे ऐसा नहीं करते हैं जो लोग मानते हैं कि वे वास्तव में कर रहे हैं। वास्तविक पार्सिंग समस्याएं और उनके समाधान RegExs का कभी भी उपयोग नहीं करते हैं। क्या RegExs के साथ लिखे गए कोई कंपाइलर हैं? –

+1

@ एमपी। जब लोग कुछ स्पष्ट रूप से समझ नहीं पाते हैं तो वे अक्सर इसे "अजीब" कहते हैं; बस इसे समझने के लिए कुछ समय दें, इससे प्रयास बहुत कम हो जाता है ... – KDjava

2

आप Antlr पार्सर जेनरेटर का उपयोग कर सकते हैं ताकि आपकी फाइलों को पार्स करने में सक्षम पार्सर बनाया जा सके।

1

पार्सिंग के बारे में सवाल का जवाब नहीं दे रहा है ... लेकिन आप फ़ाइलों को पार्स कर सकते हैं और जैसे ही नई फाइलें आती हैं, स्थिर पृष्ठों को उत्पन्न कर सकते हैं। तो आपके पास कोई प्रदर्शन समस्या नहीं होगी ... (और मुझे लगता है कि 1 एमबी एक बड़ी फाइल नहीं है, इसलिए आप इसे स्मृति में लोड कर सकते हैं, जब तक आप एक साथ कई फाइलें लोड नहीं करते हैं ...)

+0

यह वही फ़ाइल है जो हर समय पार्स हो रही है - इसे स्पष्ट करने के लिए पोस्ट संपादित करें। –

1

एक साधारण पर्याप्त फ़ाइल प्रारूप की तरह लगता है, तो आप Recursive Descent Parser का उपयोग करने पर विचार कर सकते हैं। जावासीसी और एंट्लर की तुलना में, इसके पेशेवर यह हैं कि आप कुछ सरल तरीकों को लिख सकते हैं, आपको आवश्यक डेटा प्राप्त कर सकते हैं, और आपको एक पार्सर जेनरेटर औपचारिकता सीखने की आवश्यकता नहीं है। इसकी विपक्ष - यह कम कुशल हो सकती है। एक पुनरावर्ती मूल पार्सर नियमित अभिव्यक्तियों से सिद्धांत रूप से मजबूत है। यदि आप इस फ़ाइल प्रकार के लिए व्याकरण के साथ आ सकते हैं, तो यह आपके द्वारा चुने गए समाधान के लिए आपकी सेवा करेगा।

1

यदि यह जावा रेगेक्स की सीमाएं हैं तो आप इसके बारे में सोच रहे हैं, इसके बारे में चिंता न करें । मान लीजिए कि आप regexes क्राफ्टिंग में उचित रूप से सक्षम हैं, प्रदर्शन एक समस्या नहीं होनी चाहिए। सुविधा सेट भी संतोषजनक रूप से समृद्ध है - मेरे पसंदीदा, possessive quantifiers सहित।

1

दूसरा समाधान प्रीप्रोकैसिंग (ऑफलाइन, या क्रॉन जॉब के रूप में) के कुछ रूपों को करना है जो एक बहुत ही अनुकूलित डेटा संरचना उत्पन्न करता है, जिसका उपयोग तब कई वेब अनुरोधों (फ़ाइल को दोबारा पोस्ट किए बिना) करने के लिए किया जाता है। ।

हालांकि, प्रश्न में परिदृश्य को देखते हुए, ऐसा लगता है कि इसकी आवश्यकता नहीं है।

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