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();
}
}
}