private void ReadLogFile() { _running = true; _offset = FindInitialOffset(); Util.DebugLog?.WriteLine($"LogWatcher.ReadLogFile: offset={_offset}"); while (!_stop) { var fileInfo = new FileInfo(_info.FilePath); if (fileInfo.Exists) { if (!_logFileExists) { _logFileExists = true; OnLogFound?.Invoke(this, new LogFoundEventArgs(_info.Name)); Util.DebugLog?.WriteLine("LogWatcher.ReadLogFile: found " + _info.Name); } using (var fs = new FileStream(_info.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { fs.Seek(_offset, SeekOrigin.Begin); if (fs.Length == _offset) { Thread.Sleep(_readDelay); continue; } var lines = new List <LogLineItem>(); using (var sr = new StreamReader(fs)) { string line; while (!sr.EndOfStream && (line = sr.ReadLine()) != null) { if (line.StartsWith("D ")) { var next = sr.Peek(); if (!sr.EndOfStream && !(next == 'D' || next == 'W')) { break; } var logLine = new LogLineItem(_info.Name, line); if ((!_info.HasFilters || (_info.StartsWithFilters?.Any(x => logLine.LineContent.StartsWith(x)) ?? false) || (_info.ContainsFilters?.Any(x => logLine.LineContent.Contains(x)) ?? false)) && logLine.Time >= _startingPoint) { lines.Add(logLine); } } else { OnIgnoredLine?.Invoke(this, new RawLogLineEventArgs(line)); } _offset += Encoding.UTF8.GetByteCount(line + Environment.NewLine); } } OnNewLine?.Invoke(this, new LogLineEventArgs(lines)); } } Thread.Sleep(_readDelay); } _running = false; }
private long FindInitialOffset() { var fileInfo = new FileInfo(_info.FilePath); if (fileInfo.Exists) { using (var fs = new FileStream(_info.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var sr = new StreamReader(fs, Encoding.ASCII)) { var offset = 0; while (offset < fs.Length) { var sizeDiff = 4096 - Math.Min(fs.Length - offset, 4096); offset += 4096; var buffer = new char[4096]; fs.Seek(Math.Max(fs.Length - offset, 0), SeekOrigin.Begin); sr.ReadBlock(buffer, 0, 4096); var skip = 0; for (var i = 0; i < 4096; i++) { skip++; if (buffer[i] == '\n') { break; } } offset -= skip; var lines = (new string(buffer.Skip(skip).ToArray())).Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToArray(); for (int i = lines.Length - 1; i > 0; i--) { if (string.IsNullOrWhiteSpace(lines[i].Trim('\0'))) { continue; } var logLine = new LogLineItem(_info.Name, lines[i]); if (logLine.Time < _startingPoint) { var negativeOffset = lines.Take(i + 1).Sum(x => Encoding.UTF8.GetByteCount(x + Environment.NewLine)); return(Math.Max(fs.Length - offset + negativeOffset + sizeDiff, 0)); } } } } } return(0); }