tags:

views:

445

answers:

3

If I'm reading a text file in shared access mode and another process truncates it, what is the easiest way to detect that? (I'm excluding the obvious choice of refreshing a FileInfo object periodically to check its size) Is there some convenient way to capture an event? (Filewatcher?)

+3  A: 

There is, It's called FileSystemWatcher.

If you are developing a windows forms application, you can drag-and-drop it from the toolbox.

Here's some usage example:

private void myForm_Load(object sender, EventArgs e)
{
    var fileWatcher = new System.IO.FileSystemWatcher();

    // Monitor changes to PNG files in C:\temp and subdirectories
    fileWatcher.Path = @"C:\temp";
    fileWatcher.IncludeSubdirectories = true;
    fileWatcher.Filter = @"*.png";

    // Attach event handlers to handle each file system events
    fileWatcher.Changed += fileChanged;
    fileWatcher.Created += fileCreated;
    fileWatcher.Renamed += fileRenamed;

    // Start monitoring!
    fileWatcher.EnableRaisingEvents = true;
}

void fileRenamed(object sender, System.IO.FileSystemEventArgs e)
{
    // a file has been renamed!
}

void fileCreated(object sender, System.IO.FileSystemEventArgs e)
{
    // a file has been created!
}

void fileChanged(object sender, System.IO.FileSystemEventArgs e)
{
    // a file is modified!
}

It's in System.IO and System.dll so you should be able to use it in most type of projects.

chakrit
Didn't knew that. +1
Daok
As my post suggests, I thought of this, but I was curious if there are any other solutions. I'm voting your answer up anyway, because you gave such nice sample code! ;-)
dviljoen
Well.. you were asking for a "convenient" way... I don't think there is anything more convenient... other than maybe redesign your approach to the problem as @petercrabtree said below. And thanks for the +1, I'm getting close to getting another ability on SO :-)
chakrit
Even though I ended up solving it a different way, this is probably the best answer, so there you go. Thanks.
dviljoen
A: 

Just something to chew on; it may not apply to your situation:

chakrit's solution is correct for what you asked for, but I have to ask -- why are you reading a file while another process truncates it?

In particular, if you don't have some synchronization, reading/writing files concurrently is not particularly safe, and you may find you have other mysterious problems.

Peter Crabtree
I'm essentially creating a tail command for windows... I really didn't want to mention that because now that I have, keyboards are getting beat to death all over the internet by people having strokes over the fact that there are plenty of other implementations of it already available.
dviljoen
+2  A: 

FSW cannot work reliably, it is asynchronous. Assuming you don't get an exception, StreamReader.ReadLine() will return null when the file got truncated. Then check if the size changed. Beware of the unavoidable race condition, you'll need to verify assumptions about timing.

Hans Passant
Yes. But ReadLine() also returns null when you're at the end of the file. I suppose I can just check the file size anytime I get a null. I think I'll give that a try. Thanks. BTW, just because its asynchronous doesn't mean it's not reliable. (Or is that not what you meant?)
dviljoen
Since it is asynchronous, you're much more likely to get an EOF before you get the FSW notification. That's an unavoidable race condition you can avoid.
Hans Passant