2010-12-17 11 views
5

परिदृश्य:एक महंगा ऑपरेशन कास्टिंग कर रहा है?

  • मैं एक बड़ी फ़ाइल (चरित्र फ़ाइल) को पार्स कर रहा हूँ। उदाहरण के लिए एक .csv फ़ाइल (बिल्कुल मेरा मामला नहीं)
  • मैं पूरी फ़ाइल को स्मृति में नहीं रख सकता। तो मुझे एक बफर रणनीति लागू करनी होगी।
  • मैं एक सामान्य हैंडलर बनाना चाहता हूं जो स्मृति में लगातार पंक्तियों (स्ट्रिंग्स के रूप में) रखेगा। अनियंत्रित रेखाओं को हटाते समय यह हैंडलर अन्य लाइनों को लाता है।
  • इस हैंडलर पर मैं एक पार्सर का निर्माण करूंगा जो लाइनों को जावा ऑब्जेक्ट्स में बदल देगा और उन वस्तुओं पर परिवर्तन संचालित करेगा। एक बार परिवर्तन किए जाने के बाद (ऑब्जेक्ट्स पर कुछ फ़ील्ड्स अपडेट करें) फ़ाइलों को वापस फाइलों में रखें।

मैं चाहिए:

  • के बजाय तार की एक सरणी के रूप में बफर रखने के लिए, मैं बफर सीधे वस्तुओं (एक भी डाली कर रही है) के रूप में रखना चाहिए? या ...
  • बफर को लाइनों के रूप में रखें, हर बार जब मुझे बफर पर काम करने की आवश्यकता होती है, तो सही वस्तु पर जानकारी डालें, परिवर्तन करें, फ़ाइलों को वापस वापस रखें। अनुक्रमिक संचालन के लिए पूरक कास्ट की आवश्यकता होगी।

मुझे चीजों को सरल रखना होगा। कोई सुझाव?

+1

आप अन्य डेटा प्रकारों पर स्ट्रिंग कास्टिंग कैसे कर रहे हैं? –

+1

क्या आप कास्टिंग या पार्सिंग के बारे में बात कर रहे हैं? – fortran

+0

यह अधिक जटिल है। यह बिल्कुल/से स्ट्रिंग तक कास्ट नहीं है, एक इंटरफ़ेस पंक्ति और अधिक कार्यान्वयन है। प्रत्येक कार्यान्वयन एक कंटेनर की तरह है, जो एक वस्तु देता है। उस वस्तु को कास्ट किया जाना चाहिए। अगर मुझे एक विशिष्ट पंक्ति पर कुछ बदलाव करना है, तो आंतरिक तंत्र में कुछ जानवरों की आवश्यकता होती है। –

उत्तर

8

कास्टिंग किसी ऑब्जेक्ट पर मौजूद स्मृति की मात्रा को नहीं बदलता है। यह सिर्फ रनटाइम प्रकार बदलता है।

यदि आप प्रति-पंक्ति के आधार पर उन परिचालनों को कर सकते हैं, तो बस उस लूप के अंदर ऑपरेशन करें जहां आप एक पंक्ति पढ़ते हैं।

while ((line = reader.readLine()) != null) { 
    line = process(line); 
    writer.println(line); 
} 

इस तरह आप पूरी फ़ाइल के बजाए हर बार जावा की मेमोरी में केवल एक पंक्ति के साथ प्रभावी रूप से समाप्त होते हैं।

या यदि आपको पूरी सीएसवी फ़ाइल के आधार पर उन परिचालनों की आवश्यकता है (यानी, वे ऑपरेशन पर सभी पंक्तियों पर निर्भर हैं), तो आपकी सबसे कुशल शर्त एक वास्तविक SQL डेटाबेस में CSV फ़ाइल आयात करना है और फिर डेटा को बदलने के लिए SQL कथन का उपयोग करें और फिर इसे CSV फ़ाइल में फिर से निर्यात करें।

3

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

2

जावा निर्मोक:

Object a = new String(); 
String b (String) a; 

की तरह महंगा नहीं हैं। - कोई फर्क नहीं पड़ता कि आप स्ट्रिंग्स या किसी अन्य प्रकार कास्ट करते हैं।

1

आपका वास्तविक मूल्य जोड़ने प्रत्येक पंक्ति को स्ट्रिंग के रूप में पढ़ना होगा, जो जावा में बहुत आसान है।यह एक स्ट्रिंग में है के बाद, इसके साथ

String[] row = parsedRow.split(",");

प्रत्येक अल्पविराम पर स्ट्रिंग विभाजित करने के लिए आप जो तब पर संचालित किया जा सकता सरणी में प्रत्येक मान, के लिए एक स्ट्रिंग होगा तुच्छ है।

+0

विचार करें कि आपका 'विभाजन()' कॉल '123," abc, def ", ghi' पर क्या करेगा। –

+0

@ बस मेरा सही विकल्प - विधिवत ध्यान दिया गया है, लेकिन फिर आप मेरे सरल उदाहरण के बाद एक फ्रिंज मामले में शामिल होना शुरू कर रहे हैं जो मानता है कि एक अल्पविराम हमेशा एक विभाजक होगा और स्ट्रिंग के भीतर कभी भी निहित नहीं होगा। – bakoyaro

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