ReadLine is not at all what you want to do ... open the file reader ... find the desired position, read the necessary data (in another file stream).
A "ReadLine" should really read the data ... whereas a search (myStream.Position = whereIWantToGo) is basically instantaneous.
You will handle this in the same way as a sorted database. A database with 1,000,000 records takes only 20 searches to find ... start halfway, too high? just saved 500,000 searches ... are back halfway ... too high? just shaved off another 250,000 attempts ... rinse, repeat.
If you find funny characters (bad encoding)
To your email address (by the way, you really should continue to use SO, not email - this way other people can benefit) ... The answer is that you need to try different types of encoding. Your file cannot be UTF8 encoded (this is what my code expects below). So use new StreamReader("MyLogFile.txt", Encoding.ASCII) or some other encoding until it works for you.
C # console application that should get started
Disclaimer ... this code is unpleasant and may have errors when there is an infinite loop :) ... but here is a console application that should work for you.
using System; using System.Collections.Generic; using System.Globalization; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // example dates var lookFor = new DateTime(2012, 12, 14, 16, 20, 02); var readUntilDate = new DateTime(2012, 12, 14, 16, 20, 05); using (var stream = File.OpenText("MyLogFile.txt")) { if (SeekToEntry(stream, lookFor) == false) { Console.WriteLine("Could not find entry for date {0}", lookFor); return; } foreach (var line in ReadEntriesUntil(stream, readUntilDate)) { Console.WriteLine("Line: {0}", line); } } } // This method simply spits out one line at a time until it hits // the target cut-off. static IEnumerable<string> ReadEntriesUntil(StreamReader stream, DateTime target) { while (true) { string line = stream.ReadLine(); if (line == null) { break; } if (line.StartsWith("!<<")) { DateTime entryDate; if (DateTime.TryParseExact(line.Substring(3, 19).Replace(".", ""), @"ddMMyyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out entryDate)) { if (entryDate >= target) { break; } } } yield return line; } } // This method will bounce around the stream till it finds your // target entry date. static bool SeekToEntry(StreamReader stream, DateTime target) { long from = 0; long to = stream.BaseStream.Length; while (true) { long testIndex = (to - from) / 2; stream.BaseStream.Seek(testIndex, SeekOrigin.Begin); var entryDate = GetNextEntryDate(stream, out testIndex); if (entryDate == null || (from == to)) { return false; } switch (entryDate.Value.CompareTo(target)) { case -1: // Found too low... from = testIndex; break; case 1: // Fount too high... to = testIndex; break; default: return true; } } } // This is a function that is meant to keep seeking forward until // it hits an entry date. static DateTime? GetNextEntryDate(StreamReader stream, out long actualIndex) { actualIndex = stream.BaseStream.Position; DateTime? result = null; string line = null; // Find the next entry. while ((line = stream.ReadLine()) != null && line.StartsWith("!<<") == false) ; if (line != null) { actualIndex = stream.BaseStream.Position - line.Length; DateTime timeStamp; if (DateTime.TryParseExact(line.Substring(3, 19).Replace(".", ""), @"ddMMyyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out timeStamp)) { result = timeStamp; } } return result; } } }