We have a long-running legacy Windows application which cannot be updated for various reasons. This program writes out data files at unpredictable intervals. Before it writes out a new data file, it first renames the previous data file.
Other applications (well, at least one!) need real-time access to the latest data file. The problem is that if the reader program has the file open when the writer program tries to rename it, the writer program crashes. This must not happen!
The obvious solution, fixing the writer program, is not practical. What I would like to find is some Windows service or alternative file system which would transparently copy files as they are written. This way the reader program could access the copied file without disturbing the writer program (it matters much less if the reader program gets a fault).
As far as I can tell, disk mirroring would not solve the file-locking issue we have.
My question: does anyone know of such a service we could use?
EDIT: example code illustrating the problem, even with supposedly non-locking file reads:
const string SrcFilePath = @"C:\Foo.txt";
const string DestFilePath = @"C:\Bar.txt";
void Main()
{
Task.Run(() =>
{
while (true)
{
try
{
Console.WriteLine("Writer: moving {0} to {1}", SrcFilePath, DestFilePath);
File.Move(SrcFilePath, DestFilePath);
Console.WriteLine("Writer: writing {0}", SrcFilePath);
File.WriteAllText(SrcFilePath, "Hello, World!\n");
}
catch (Exception e)
{
Console.WriteLine("Writer: error: {0}", e.Message);
}
Console.WriteLine("Writer: sleeping.");
Task.Delay(1000).Wait();
}
});
Task.Run(() =>
{
while (true)
try
{
Console.WriteLine("Reader: opening {0}", SrcFilePath);
var fs = new FileStream(SrcFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Console.WriteLine("Reader: sleeping...");
Task.Delay(1500).Wait(); // Simulate a context switch in the middle of a file read.
Console.WriteLine("Reader: waking up.");
Console.WriteLine("Reader: closing {0}", SrcFilePath);
fs.Dispose();
}
catch (Exception e)
{
Console.WriteLine("Reader: error: {0}", e.Message);
}
});
}
This fails like so:
Reader: opening C:\Foo.txt
Reader: sleeping...
Writer: moving C:\Foo.txt to C:\Bar.txt
Writer: error: The process cannot access the file because it is being used by another process.
Writer: sleeping.
Reader: waking up.
Reader: closing C:\Foo.txt