2013-05-01 9 views
5

मैं समय-समय पर की जाती है कि यह भी लिखा जा रहा एक लॉग फ़ाइल पढ़ना चाहते हैं के अंतिम भाग को पढ़ने के लिए। कार्यक्रम समय-समय पर लॉग फ़ाइल सामग्री पढ़ रहा होगा और कुछ मान निकालने के लिए इसे पार्स कर देगा। लेकिन मैं हर बार पूरी फाइल नहीं पढ़ना चाहता हूं।सी # - सबसे प्रभावी तरीका समय-समय पर एक फ़ाइल

क्या किसी विशेष पंक्ति से फ़ाइल को पढ़ने का कोई तरीका है?

उदाहरण के लिए पहले पढ़ने पर फ़ाइल में 100 लाइनें हैं। मैं इस मान को नोट करता हूं और अगली बार जब मैं पढ़ता हूं तो मैं लाइन 100 से आगे पढ़ना शुरू करता हूं और वर्तमान फ़ाइल की लाइन नंबर स्टोर करता हूं।

वहाँ यह करने के लिए एक कारगर तरीका है? लॉग फ़ाइल लगभग 100 एमबी तक बढ़ेगी और मुझे हर 5 सेकंड के बारे में पढ़ने की जरूरत है। तो यह हर बार पूरी फाइल को पढ़ने के लिए सक्षम नहीं होगा।

कोई भी सुझाव बहुत सराहना कर रहा है।

+2

आप Tail.NET http://www.codeproject.com/Articles/7568/Tail-NET पर देखने – itsmatt

+0

आप एकाधिक फ़ाइलों में फ़ाइल या DB इस तरह के एक उद्देश्य के लिए इरादा विभाजन सकता है हो सकता है। हालांकि, मुझे यकीन नहीं है कि केवल 100 एमबी फ़ाइल के साथ कितना लाभ प्रदान करता है। धाराओं में इंडेक्स शुरू होते हैं। इसका उपयोग क्यों न करें? –

उत्तर

3

मुझे लगता है कि आप इसकी तलाश कर रहे हैं, जहां ऑफ़सेट यह होगा कि आप कितना बैकट्रैक चाहते हैं। संदर्भ: MSDN

using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) 
{ 
    fs.Seek(offset, SeekOrigin.End); 
} 

अब filestream हालांकि अब तक आप सेट फ़ाइल में वापस की ओर इशारा करते है होना करने के लिए 'ऑफसेट', और आप यहां से पढ़ सकते हैं।

+0

... हाँ, मैं दो मिनट बहुत धीमी हूं;) –

+0

@bland धन्यवाद। मैं इस विधि को देख लूंगा। ऐसा लगता है कि यह मेरे लिए काम कर सकता है। – madu

2

अगर लॉग केवल जोड़ा गया है, तो आप लॉक के बिना केवल-पढ़ने के लिए फ़ाइल खोलने का प्रयास कर सकते हैं। इस तरह अन्य प्रक्रियाएं इसे पढ़ने के दौरान लिख सकती हैं।

var fs = new FileStream(path,FileMode.Open,FileAccess.Read, FileShare.ReadWrite); 
+0

यदि आपको फ़ाइल की लंबाई याद है, तो आप अगले स्थान पर उस स्थान पर 'खोज' कर सकते हैं। – JosephHirn

1

कुछ तेज और गंदे के लिए, मैं इस का उपयोग करें। इस मामले में यह एक लॉग डंप है - मैं वास्तव में के बारे में कितने लाइनों मैं, मैं सिर्फ एक गुच्छा अंत (numBytes) पर चाहते हैं परवाह नहीं है:

cmdLogReader = new System.IO.StreamReader(cmdLogFileIn); 

if (cmdLogReader.BaseStream.Length < (numBytes - 1)) { 
    return cmdLogReader.ReadToEnd; 
} else { 
    cmdLogReader.BaseStream.Seek(-numBytes, System.IO.SeekOrigin.End); 
    cmdLogReader.ReadLine(); 
    return cmdLogReader.ReadToEnd;   
} 

तुम हमेशा शुरुआत में BaseStream.Length बचा सकता है और इसका उपयोग यह गणना करने के लिए करें कि अगली बार कितनी दूर जाना है (यानी: numBytesBaseStream.Length - previousBaseStreamLength या जो कुछ भी हो जाता है), जो अनुक्रमिक कॉल को आखिरी पढ़ने के बाद जो भी जोड़ा गया है उसे पकड़ लेगा।

यदि आप ऐसा करते हैं तो आपको ReadLine कॉल छोड़ना पड़ सकता है क्योंकि यह वास्तव में केवल यादृच्छिक राशि को बैकट्रैक करने के बाद निकटतम रेखा तक जाने के लिए है। यदि आप जानते हैं कि आप लाइन सीमा पर उतरने जा रहे हैं तो आप केवल ReadToEnd कर सकते हैं।

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

+0

धन्यवाद। मैं बेसस्ट्रीम। लम्बाई संपत्ति से अवगत नहीं था और फ़ाइल को पढ़ने के लिए इस विधि का उपयोग कर रहा था। मैं इस विधि में एक नज़र डालेगा। – madu

1

शोध यह अच्छी तरह से कर सकते हैं। लेकिन मैं अन्य आगे बढ़ाना चाहता हूं।

public static void Read() 
    { 
     var fs = new FileStream(@"G:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
     int lastReadCount = 0; 
     while (true) 
     { 
      var totalCountOfFile = fs.Length; 
      if (lastReadCount < totalCountOfFile) 
      { 
       var buffer = new byte[1024]; 
       int count = fs.Read(buffer, 0, buffer.Length); 
       lastReadCount += count; 
       Display(buffer); 
      } 
      Thread.Sleep(5000); 
     } 
    } 

    private static void Display(byte[] buffer) 
    { 
     var text = Encoding.UTF8.GetString(buffer.Where(p=>p != 0).ToArray()); 
     Console.Write(text); 
    } 
संबंधित मुद्दे