2009-09-11 12 views
16

सी #/.NET (विंडोज़ पर) में फ़ाइल स्ट्रीम का उपयोग करके "बढ़ती" फ़ाइल पढ़ने का कोई तरीका है? फाइलस्ट्रीम खोले जाने पर फ़ाइल की लंबाई बहुत छोटी होगी, लेकिन फ़ाइल को दूसरे थ्रेड द्वारा लिखा जा रहा है। अगर/जब filestream दूसरे धागे को "पकड़ता है" (यानी Read() 0 बाइट्स पढ़ता है), मैं फ़ाइल को थोड़ा बफर करने की अनुमति देने के लिए रोकना चाहता हूं, फिर पढ़ना जारी रखें।सी # में बढ़ती हुई फाइल से पढ़ें?

मैं वास्तव में FilesystemWatcher का उपयोग नहीं करना चाहता हूं और नई फ़ाइल स्ट्रीम (जैसे लॉग फाइलों के लिए सुझाया गया था) बनाना जारी रखता हूं, क्योंकि यह लॉग फ़ाइल नहीं है (यह एक वीडियो फ़ाइल फ्लाई पर एन्कोड किया गया है) और प्रदर्शन एक मुद्दा है

धन्यवाद,
रॉबर्ट

+0

मैं अपने जवाब अपडेट किया गया। –

उत्तर

6

आप यह कर सकते हैं, लेकिन आपको फ़ाइल को Stream.Seek का उपयोग करके और थ्रेड के बीच उपयुक्त सिंक्रनाइज़ेशन का उपयोग करके स्थिति को पढ़ने और लिखने की सावधानीपूर्वक ट्रैक रखने की आवश्यकता है। आम तौर पर आप डेटा के लिए सिंक्रनाइज़ेशन करने के लिए EventWaitHandle या उप-वर्ग का उपयोग करेंगे, और आपको FileStream ऑब्जेक्ट तक पहुंच के लिए सिंक्रनाइज़ेशन पर विचार करने की आवश्यकता होगी (शायद lock कथन के माध्यम से)।

अद्यतन:this question का जवाब देने में मैंने कुछ ऐसा ही लागू किया - एक ऐसी स्थिति जहां पृष्ठभूमि में एक फ़ाइल डाउनलोड की जा रही थी और साथ ही साथ अपलोड की जा रही थी। मैंने मेमोरी बफर का इस्तेमाल किया, और gist पोस्ट किया जिसमें कामकाजी कोड है। (यह जीपीएल है, लेकिन है कि आप के लिए कोई फर्क नहीं सकता है - किसी भी मामले में आप अपने खुद के बात करने के लिए सिद्धांतों का उपयोग कर सकते हैं।)

+0

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

4

तरह से मैं इस DirectoryWatcher/FileSystemWatcher वर्ग उपयोग कर रहा है, और जब यह फाइल पर चलाता है आप आप एक FileStream खोलने के लिए और अंत करने के लिए इसे पढ़ा चाहते हल किया। और जब मैंने पढ़ा तो मैं पाठक की स्थिति को सहेजता हूं, इसलिए अगली बार DirectoryWatcher/फाइलसिस्टम वाटर ट्रिगर करता है कि मैं एक स्ट्रीम खोलता हूं जहां मैं पिछली बार था।

कॉलिंग फ़ाइलस्ट्रीम। लम्बाई वास्तव में बहुत धीमी है, मेरे पास मेरे समाधान के साथ कोई प्रदर्शन समस्या नहीं है (मैं 10 एमबी से 50 आईएसएच तक "लॉग" पढ़ रहा था)।

मेरे लिए जो समाधान मैं वर्णन करता हूं वह बहुत आसान और बनाए रखने में आसान है, मैं इसे आज़माउंगा और इसे प्रोफाइल करूंगा। मुझे नहीं लगता कि आप इसके आधार पर कोई प्रदर्शन समस्याएं प्राप्त करने जा रहे हैं। मैं ऐसा करता हूं जब पीपीएल एक बहु थ्रेडेड गेम खेल रहा है, अपना पूरा सीपीयू ले रहा है और किसी ने शिकायत नहीं की है कि मेरा पार्सर प्रतिस्पर्धी पार्सर्स की मांग कर रहा है।

+1

प्रश्न विशेष रूप से प्रदर्शन चिंताओं के कारण एक दर्शक का उपयोग करके छूट देता है। –

+0

हाँ मैंने देखा। preformance के बारे में मेरे जवाब में और जोड़ा। – EKS

+0

आपको पाठक में FileStream.Length को कॉल करने की आवश्यकता नहीं है यदि आप जो भी कर रहे हैं, वह पढ़ रहा है, तो आप जितना दूर कर सकते हैं, फिर अधिक डेटा की प्रतीक्षा कर रहे हैं। दर्शक ट्रिगरिंग के लिए आप किस तरह की विलंबता देख रहे हैं? क्या यह मशीन लोड के आधार पर बदलता है? –

2

एक अन्य बात यह है कि उपयोगी हो सकता है FileStream वर्ग एक संपत्ति पर यह ReadTimeOut कहा जाता है जो है के रूप में परिभाषित:

मिलीसेकंड में एक मान प्राप्त करता है या सेट करता है, यह निर्धारित करता है कि स्ट्रीम समय से पहले कितनी देर तक पढ़ने का प्रयास करेगा। (स्ट्रीम से विरासत में मिला)

यह तब उपयोगी हो सकता है जब आपके पढ़ने को आपके लिखने के लिए पकड़ लेते हैं, तो पाठ लिखने वाले धागे रोक सकते हैं जबकि लिखने वाले बफर को फिसल जाता है। यह निश्चित रूप से यह देखने के लिए एक छोटा परीक्षण लिखने लायक होगा कि यह संपत्ति किसी भी तरह से आपके कारण की सहायता करेगी या नहीं।

क्या एक ही वस्तु पर पढ़ने और लिखने के संचालन हो रहे हैं? यदि ऐसा है तो आप फ़ाइल पर अपने स्वयं के अवशेष लिख सकते हैं और फिर क्रॉस थ्रेड संचार कोड लिख सकते हैं जैसे कि धागा लिखने वाला धागा और धागे को सूचित करते समय पढ़ता है ताकि पढ़ा जा सके धागा पढ़ना बंद करना कब जानता है जब यह ईओएफ तक पहुंचता है।

+0

फ़ाइलस्ट्रीम पर ReadTimeOut को सेट अप करने पर अपवाद को फेंकने पर यह उत्तर +3 कैसे प्राप्त हो सकता है? : एस –

4

यह एक फ़ाइल के चारों ओर एक StreamReader के साथ काम किया, निम्न चरणों के साथ:

  1. कार्यक्रम है कि फाइल करने के लिए लिखते हैं में, पढ़ने के लिए साझा करने के साथ इसे खोलने, इस तरह:

    var out = new StreamWriter(File.Open("logFile.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read)); 
    
  2. कार्यक्रम है कि फ़ाइल पढ़ता है, साझा करने पढ़ने-लिखने की साथ इसे खोलने के लिए इस प्रकार है:

    using (FileStream fileStream = File.Open("logFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
    using (var file = new StreamReader(fileStream)) 
    
  3. इनपुट स्ट्रीम तक पहुंचने से पहले, जांचें कि अंत तक पहुंच गया है, और यदि ऐसा है, तो थोड़ी देर प्रतीक्षा करें।

    while (file.EndOfStream) 
    { 
        Thread.Sleep(5); 
    } 
    
संबंधित मुद्दे