跟踪流读取器线的位置
嗨伙计们,我需要做的是跟踪我从流阅读器读取的行的位置当我说reader.ReadLine()
我需要知道该行在文件中的位置,我也希望能够然后从我之前跟踪过的位置读取文件。
这可能吗? 如果是这样请协助。
非常感谢帮助
提前致谢。
你可以这三种方式之一:
1)编写自己的StreamReader。 这是一个很好的起点: 如何知道文本文件中流读取器的位置(亚麻)?
2)StreamReader类有两个非常重要但私有的变量,称为charPos和charLen,用于定位实际的“读取”位置,而不仅仅是流的底层位置。 您可以使用reflection来获取此处建议的值
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相同)是读取行并将行存储在数组中。 如果要读取前一行,只需使用该数组。
也许这可以帮到你
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; /// /// CurrentLine number /// public long CurrentPosition { get { return _CurrentPosition; } } /// /// CurrentLine number /// public int CurrentLine { get { return _CurrentLine; } } /// /// Constructor /// /// Stream public StreamLineReader(Stream stream) { _Base = stream; } /// /// Count lines and goto line number /// /// Goto Line number /// Return true if goTo sucessfully public bool GoToLine(int goToLine) { return IGetCount(goToLine, true) == goToLine; } /// /// Count lines and goto line number /// /// Goto Line number /// Return the Count of lines public int GetCount(int goToLine) { return IGetCount(goToLine, false); } /// /// Internal method for goto&Count /// /// Goto Line number /// Stop when found the selected line number /// Return the Count of lines 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; } /// /// Read Line /// /// 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(); } /// /// Free resources /// 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(); }