2012-04-17 16 views
11

हाय दोस्तों जो मुझे करने की ज़रूरत है वह है कि मैं स्ट्रीम रीडर से पढ़ रहा हूं, जब मैं reader.ReadLine() फ़ाइल में उस पंक्ति की स्थिति जानना चाहता हूं और मैं उस स्थिति से फ़ाइल को पढ़ने में सक्षम होना चाहता हूं जिसे मैंने पहले ट्रैक किया था।स्ट्रीमर की लाइन की स्थिति को ट्रैक करना

क्या यह संभव है? यदि ऐसा है तो कृपया सहायता करें।

सहायता बहुत सराहना की है

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

+0

क्या आप के लिए, कितना बड़ा फ़ाइलें हैं इस की क्या ज़रूरत है, ... –

उत्तर

17

आप कर तीन तरीकों में से यह एक कर सकते हैं:

1) अपनी खुद की StreamReader लिखें। यहां शुरू करने के लिए एक अच्छी जगह है: How to know position(linenumber) of a streamreader in a textfile?

2) स्ट्रीमरडर वर्ग में दो बहुत ही महत्वपूर्ण हैं, लेकिन निजी चर को charPos और charLen कहा जाता है जिन्हें वास्तविक "पढ़ने" स्थिति का पता लगाने की आवश्यकता होती है न कि केवल स्ट्रीम की अंतर्निहित स्थिति। सुझाव के रूप में here

Int32 charpos = (Int32) s.GetType().InvokeMember("charPos", 
BindingFlags.DeclaredOnly | 
BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.Instance | BindingFlags.GetField 
,null, s, null); 

Int32 charlen= (Int32) s.GetType().InvokeMember("charLen", 
BindingFlags.DeclaredOnly | 
BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.Instance | BindingFlags.GetField 
,null, s, null); 

return (Int32)s.BaseStream.Position-charlen+charpos; 

3 आप प्रतिबिंब का उपयोग मूल्यों को प्राप्त करने के लिए कर सकता है) बस एक स्ट्रिंग सरणी में पूरी फ़ाइल पढ़ें। कुछ इस तरह:

char[] CRLF = new char[2] { '\n', '\r' }; 
TextReader tr = File.OpenText("some path to file"); 
string[] fileLines = tr.ReadToEnd().Split(CRLF); 

एक और संभावना है (# 3 के रूप में sames तर्ज पर) लाइनों में पढ़ सकते हैं और एक सरणी में लाइन स्टोर करने के लिए है। जब आप पूर्व पंक्ति को पढ़ना चाहते हैं, तो बस सरणी का उपयोग करें।

+0

प्रतिक्रिया के लिए धन्यवाद, लेकिन मैं कोशिश की है आउट समाधान # 2 लेकिन मुझे नहीं लगता कि यह मुझे वर्तमान स्थिति/रेखा देता है जो मैं वर्तमान में स्ट्रीमreader के साथ पढ़ रहा हूं। रीडलाइन() विधि। और एक निर्दिष्ट पंक्ति/स्थिति से फ़ाइल को पढ़ने शुरू करने का कोई तरीका भी है? अग्रिम धन्यवाद। – johnnie

+0

@johnie - संभवतः BaseStream.Position = N को सेट करके और StreamReader का उपयोग करके। पढ़ें()। मुझे लगता है कि कैश किए गए लाइनों का अपना संग्रह रखना बेहतर होगा ताकि आप फ़ाइल पर वापस जाकर लाइन नंबर से किसी भी पंक्ति को फिर से पढ़ सकें। हालांकि, यह बड़ी फ़ाइलों के साथ स्मृति मुद्दों को पेश कर सकता है। –

+0

समस्या है जिसके साथ मैं झूठ बोल रहा हूं, फ़ाइल जिसे मुझे किसी निश्चित रेखा से पढ़ने की आवश्यकता है, एक बड़ी फाइल होगी और प्रत्येक पंक्ति को पढ़ने के लिए मुझे एक निश्चित स्थिति को पढ़ने के लिए पढ़ना होगा, जिसे मैं पढ़ना चाहता हूं। इसलिए मैं वर्तमान स्थिति पाने के लिए एक रास्ता खोजने की कोशिश कर रहा हूं और फिर उसे सहेजता हूं और इसे वहां से पढ़ता हूं। – johnnie

2

हो सकता है कि यह मदद कर सकते हैं

public class StreamLineReader : IDisposable 
    { 
     const int BufferLength = 1024; 

     Stream _Base; 
     int _Read = 0, _Index = 0; 
     byte[] _Bff = new byte[BufferLength]; 

     long _CurrentPosition = 0; 
     int _CurrentLine = 0; 

     /// <summary> 
     /// CurrentLine number 
     /// </summary> 
     public long CurrentPosition { get { return _CurrentPosition; } } 
     /// <summary> 
     /// CurrentLine number 
     /// </summary> 
     public int CurrentLine { get { return _CurrentLine; } } 
     /// <summary> 
     /// Constructor 
     /// </summary> 
     /// <param name="stream">Stream</param> 
     public StreamLineReader(Stream stream) { _Base = stream; } 
     /// <summary> 
     /// Count lines and goto line number 
     /// </summary> 
     /// <param name="goToLine">Goto Line number</param> 
     /// <returns>Return true if goTo sucessfully</returns> 
     public bool GoToLine(int goToLine) { return IGetCount(goToLine, true) == goToLine; } 
     /// <summary> 
     /// Count lines and goto line number 
     /// </summary> 
     /// <param name="goToLine">Goto Line number</param> 
     /// <returns>Return the Count of lines</returns> 
     public int GetCount(int goToLine) { return IGetCount(goToLine, false); } 
     /// <summary> 
     /// Internal method for goto&Count 
     /// </summary> 
     /// <param name="goToLine">Goto Line number</param> 
     /// <param name="stopWhenLine">Stop when found the selected line number</param> 
     /// <returns>Return the Count of lines</returns> 
     int IGetCount(int goToLine, bool stopWhenLine) 
     { 
      _Base.Seek(0, SeekOrigin.Begin); 
      _CurrentPosition = 0; 
      _CurrentLine = 0; 
      _Index = 0; 
      _Read = 0; 

      long savePosition = _Base.Length; 

      do 
      { 
       if (_CurrentLine == goToLine) 
       { 
        savePosition = _CurrentPosition; 
        if (stopWhenLine) return _CurrentLine; 
       } 
      } 
      while (ReadLine() != null); 

      // GoToPosition 

      int count = _CurrentLine; 

      _CurrentLine = goToLine; 
      _Base.Seek(savePosition, SeekOrigin.Begin); 

      return count; 
     } 
     /// <summary> 
     /// Read Line 
     /// </summary> 
     /// <returns></returns> 
     public string ReadLine() 
     { 
      bool found = false; 

      StringBuilder sb = new StringBuilder(); 
      while (!found) 
      { 
       if (_Read <= 0) 
       { 
        // Read next block 
        _Index = 0; 
        _Read = _Base.Read(_Bff, 0, BufferLength); 
        if (_Read == 0) 
        { 
         if (sb.Length > 0) break; 
         return null; 
        } 
       } 

       for (int max = _Index + _Read; _Index < max;) 
       { 
        char ch = (char)_Bff[_Index]; 
        _Read--; _Index++; 
        _CurrentPosition++; 

        if (ch == '\0' || ch == '\n') 
        { 
         found = true; 
         break; 
        } 
        else if (ch == '\r') continue; 
        else sb.Append(ch); 
       } 
      } 

      _CurrentLine++; 
      return sb.ToString(); 
     } 
     /// <summary> 
     /// Free resources 
     /// </summary> 
     public void Dispose() 
     { 
      if (_Base != null) 
      { 
       _Base.Close(); 
       _Base.Dispose(); 
       _Base = null; 
      } 
     } 
    } 

उपयोग:

using (StreamLineReader st = new StreamLineReader(File.OpenRead("E:\\log.txt"))) 
     { 
      bool ok = st.GoToLine(1); 
      int count= st.GetCount(0); 

      string w0 = st.ReadLine(); 
      string w1 = st.ReadLine(); 
      string w2 = st.ReadLine(); 
      string w3 = st.ReadLine(); 
     } 
संबंधित मुद्दे