2010-12-04 6 views
5

मेरे पास एक सीएसवी फ़ाइल है, जिसे स्क्रिप्ट द्वारा लगातार लिखा जा रहा है। यह टाइमस्टैंप और प्रति पंक्ति कुछ अन्य डेटा लिखता है। मुझे पहले नवीनतम डेटा पढ़ना है। वर्तमान में मैं जावा में RandomAccessFile का उपयोग कर रहा हूं ताकि फ़ाइल को विपरीत तरीके से पढ़ा जा सके। लेकिन जैसा कि इसके लगातार लिखा गया है, मुझे प्राथमिकता के साथ नया डेटा पढ़ना है। मैं रख रहा हूं कि कौन सा टाइमस्टैम्प भेजा गया है और काम कर रहा है। यह अनावश्यक स्कैनिंग परिचालन का परिणाम है।मेरे दृष्टिकोण पर सुझाव की आवश्यकता है: एक फ़ाइल को पढ़ने के लिए जो लगातार लिखा जा रहा है?

क्या इस परिदृश्य से निपटने का कोई बेहतर तरीका है?

अग्रिम धन्यवाद,

उत्तर

1

आप एक धागा है कि नई लाइनों पढ़ता के रूप में वे दिखाई देते हैं और उन्हें असंसाधित पंक्तियों के एक ढेर पर धक्का, और एक दूसरे धागा कि ढेर पॉप और रिवर्स में नई पंक्तियाँ संसाधित करता है रखने पर विचार कर सकता है आदेश।

इस पर निर्भर करते हुए कि वे कितनी जल्दी उत्पन्न होते हैं, इसकी तुलना में एक नई पंक्ति को संसाधित करने में कितना समय लगता है, यह पर्याप्त हो सकता है। यदि नई पंक्तियों को तेज़ी से उत्पन्न किया जाता है तो आप उन्हें संसाधित कर सकते हैं तो यह दृष्टिकोण शायद काम नहीं करेगा - ढेर बहुत बड़ा हो जाएगा और आप स्मृति से बाहर हो जाएंगे। उस स्थिति में, आपकी आवश्यकताओं के आधार पर, आप आकार-सीमित स्टैक से दूर हो सकते हैं जो पुराने प्रविष्टियों को त्याग देता है।

1

दो विचारों:

  1. सीएसवी के बजाय एक निश्चित आकार रिकॉर्ड स्वरूप का उपयोग करें। फिर आप यह बता सकते हैं कि न्यूलाइन की तलाश में रहने के बजाय आपके रिकॉर्ड क्या हैं।

  2. यदि यह संभव नहीं है, तो एक थ्रेड है जो फ़ाइल से आइटम पढ़ता है और उन्हें एक ढेर पर धक्का देता है। एक और थ्रेड स्टैक से आइटम पॉप करता है और उन्हें संसाधित करता है। क्योंकि यह एक ढेर है यह हमेशा सबसे हाल ही में उपलब्ध आइटम से निपटने वाला होगा। आपको यह पता लगाना होगा कि आप उन मामलों से कैसे निपटना चाहते हैं जहां स्टैक बहुत बड़ा हो जाता है। क्या आप बस इतनी पुरानी चीजें फेंकना चाहते हैं?

0

यदि आपके पास मूल स्क्रिप्ट तक पहुंच है, तो CSV फ़ाइल के अतिरिक्त, डेटाबेस को रिकॉर्ड लिखें। फिर आप डेटाबेस के साथ जो भी चाहें कर सकते हैं; अंतिम रिकॉर्ड तक पहुंचें, एक रिपोर्ट चलाएं, आदि

0

यह अनावश्यक स्कैनिंग संचालन का परिणाम देता है।

मुझे लगता है कि आप किसी बिंदु की तलाश करने के ऊपरी हिस्से का जिक्र कर रहे हैं, और फिर अगली नई सीरीज़ तक पहुंचने तक अगली मान्य सीएसवी पंक्ति प्रारंभ स्थिति को पढ़कर।

मैं इस तुलना में अधिक कुशल हो सकता है ऐसा करने के लिए तीन तरीके के बारे में सोच सकते हैं कि आप वर्तमान में क्या कर रहे हैं:

  1. पूरी फ़ाइल पढ़ें और आगे दिशा में पंक्तियों को पार्स आउट, स्मृति में पदों के भंडारण । फिर रिवर्स ऑर्डर में इन-मेमोरी पंक्तियों को संसाधित करें।

  2. पंक्ति से शुरू होने वाली शुरुआत से फ़ाइल को स्कैन करें, और स्मृति में पंक्ति प्रारंभ स्थिति को संग्रहीत करें। फिर रिवर्स ऑर्डर में पदों के माध्यम से पुनरावृत्त करें, प्रत्येक को इसी पंक्ति को पढ़ने के लिए खोज करें। (आप प्रत्येक खोज में एकाधिक पंक्तियों को संसाधित करके इनपुट को अधिक कुशलता से कर सकते हैं।)

  3. MappedByteBuffer का उपयोग कर फ़ाइल को मेमोरी में मैप करें, फिर आप पंक्ति सीमाओं को खोजने के लिए बाइट बफर आगे या पीछे से कदम उठा सकते हैं।

पहले दृष्टिकोण की आवश्यकता है कि आप स्मृति में पूरी फ़ाइल बफ़र सकते हैं, लेकिन क्योंकि आप सिस्टम कॉल की एक न्यूनतम संख्या के साथ सिर्फ एक बार फ़ाइल को पढ़ने में कम आई/ओ ओवरहेड्स है। तीसरे दृष्टिकोण में एक ही समस्या है, हालांकि आप स्मृति आवश्यकताओं को कम करने के लिए (बड़ी) खंडों में स्मृति में एक बहुत बड़ी फ़ाइल को मैप में मैप कर सकते हैं।

लेकिन आखिरकार, जावा में पीछे की फ़ाइल को पढ़ने का कोई आसान और प्रभावी तरीका नहीं है।

0

आपके आवेदन एक यूनिक्स वातावरण में चल रहा है, तो आप

tail -f /csv-file | custom-program 

कस्टम कार्यक्रम चलाने के बस मानक इनपुट स्वीकार करते हैं और अपने जावा प्रोग्राम के साथ एक गर्तिका कनेक्शन के लिए गूंज कि ​​होगा सकता है।

मुझे लगता है कि आपका जावा प्रोग्राम किसी प्रकार का सर्वर ऐप है जिसे कमांड लाइन से शुरू नहीं किया जा सकता है। यदि वह वास्तव में ठीक होगा, तो आप अपने जावा प्रोग्राम के साथ कस्टम-प्रोग्राम को प्रतिस्थापित कर सकते हैं।

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

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