0

I've been trying to read in real time a text file and display its last line in the console. The issue is that when the grows in size 300kb+ my code can't process it or just the event is not triggering. I did read pretty much all of the posts on google but can't really think of how to achieve this properly. Bear in mind that i'am super new to programming.

I'd be grateful if you can share any ideas on how to achieve this. Here is my sample code:

var wh = new AutoResetEvent(false);
        var fsw = new FileSystemWatcher(".");
        fsw.Filter = pathToFile;
        fsw.EnableRaisingEvents = true;
        fsw.Changed += (s, e) => wh.Set();

        var fs = new FileStream("c:/test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using (var sr = new StreamReader(fs))
        {
            var s = "";
            while (true)
            {
                s = sr.ReadLine();
                if (s != null && s.Contains("CActor::ClKill"))
                {
                    await b.Channel.SendMessage(s);
                    Console.WriteLine("Transmitting: " + s);
                }
                else
                {
                    Console.WriteLine("Sleeping...");
                    wh.WaitOne(1000);
                }
            }
        }

        wh.Close();

2 Answers2

0

I did find a solution to the issue.

wh.WaitOne(1000); was apparently too long and on bigger files lets say 300+ lines it had to wait a second for each line so it took a lot of time to execute.

-2

If you only want to show the last line of the file, then you can do the following:

var lastLine = File.ReadLines("c:/test.txt").Last();

As MSDN says:

When you use ReadLines, you can start enumerating the collection of strings before the whole collection is returned; when you use ReadAllLines, you must wait for the whole array of strings be returned before you can access the array. Therefore, when you are working with very large files, ReadLines can be more efficient

NicoRiff
  • 4,803
  • 3
  • 25
  • 54
  • 2
    Calling `.Last` will enumerate the _entire file_, solely to read the last line. That's not very efficient. (In fact, it's going to work almost identically to `.ReadAllLines().Last()`). Reading the code posted by the OP it seems clear to me that (despite ambiguous wording in the question) the intent is to read the tail content of the file _as it is written_ to the disk. – Dan Puzey Feb 17 '17 at 21:34
  • @DanPuzey I don´t agree with you. I think that OP is looking to read the last line to se if it equals the string "CActor::ClKill" and then do some business logic. ReadLines and ReadAllLines might take a similar time in this scenario but if it is a very large file it will be slightly faster and consume less memory – NicoRiff Feb 17 '17 at 21:41
  • Why do you say it will be faster/use less memory? The entire file still has to be read, so overall memory is the same (though there's potential for memory to be released early with `ReadLines`, if you accept the overhead of a GC...) Further, with `ReadLines` each line read is a separate disk operation - I would be more likely to assume that `ReadAllLines` does the disk access in a single pass. – Dan Puzey Feb 19 '17 at 20:36