0

I have an app (not written by me, can't modify the code) which runs in two modes - GUI-based, or silent. It writes its progress to a log file. I've written a wrapper to turn it into a pseudo-command line app, using System.Diagnostics.FileSystemWatcher to monitor the log file, and any time it changes write the latest line to the console:

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine(File.ReadAllLines(e.FullPath).Last());
}

This was working perfectly, until there were two updates to the log file in quick succession, and suddenly the app spat out an error message: System.IO.IOException: The process cannot access the file '<filepath>\Upgrader.log' because it is being used by another process.

How can I redirect the log entries to the console, without locking the file? I've found this answer, but I'm not sure how to use a FileStream to get the same effect.

EDIT:

So, if I have a dict to keep track of the log files:

Dictionary<string, FileStream> logDict = new Dictionary<string, FileStream>();
Dictionary<string, int> indexDict = new Dictionary<string, int>();

add an OnCreated event handler:

private static void OnCreated(object source, FileSystemEventArgs e)
{
    logDict[e.FullPath] = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    indexDict[e.FullPath] = 0;
    OnChanged(source, e);
}

then change OnChanged to something like

private static void OnChanged(object source, FileSystemEventArgs e)
{
    using (StreamReader sr = new StreamReader(logDict[e.FullPath]))
    {
        for (int i = 0; i < indexDict[e.FullPath]; i++)
            sr.ReadLine();
        Console.WriteLine(sr.ReadLine());
        indexDict[FullPath]++;
        sr.Close();
    }
}

that should work?

EDIT AGAIN: I think I have a solution. Tried this and it seems to work:

Dictionary<string, int> indexDict = new Dictionary<string, int>();

private static void OnChanged(object source, FileSystemEventArgs e)
{
    if (!indexDict.Keys.Contains(e.FullPath))
        indexDict[e.FullPath] = 0;
    using (FileStream fs = new FileStream(e.Full Path,
                                          FileMode.Open,
                                          FileAccess.Read,
                                          FileShare.ReadWrite))
    {
        using (StreamReader sr = new StreamReader(fs))
        {
            for (int i = 0; i < indexDict[e.FullPath]; i++)
                sr.ReadLine();
            Console.WriteLine(sr.ReadLine());
            indexDict[e.FullPath]++;
            sr.Close();
        }
    }
}
Tam Coton
  • 786
  • 1
  • 9
  • 20

0 Answers0