tags:

views:

371

answers:

5

Hello World!

I am looking for a way to determine when a particular file has changed, through .NET. (What I ultimately want is functionality that makes a copy of the file as soon as it has changed.) How can this be done?

+10  A: 

You can use a FileSystemWatcher object. This raises events on changes to files within the specified watched folder.

ck
Check the MSDN documentation, there is a possibility of a memory leak and/or out of memory exception depending on how many files you attempt to watch. Still from .net the best way of doing this is ck's answer.
Spence
+3  A: 

Microsoft Windows, and its ultimate ancestor MS-DOS, has always had an attribute on its files that indicates whether that file was changed since the last time that attribute was cleared, sort of a "dirty flag". It was used in the past by backup programs to find those files that needed to be backed up incrementally, and then cleared when a copy of that file had been made.

You can use File.GetAttributes to get the attributes on a file, and use File.SetAttributes to clear that "Archive" attribute. The next time that file is opened for writing, that archive flag will be set again.

Be careful about copying files that have been changed, as those files may still be open. You probably want to avoid concurrency problems by opening them for read exclusively when copying, and if that fails you know that file is still open for writing.

Dave Van den Eynde
+3  A: 
class Program
    {
        static void Main(string[] args)
        {
            FileSystemWatcher fsw = new FileSystemWatcher(@"c:\temp");
            fsw.Changed += new FileSystemEventHandler(fsw_Changed);
            fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);
            fsw.Renamed += new RenamedEventHandler(fsw_Renamed);
            fsw.Created += new FileSystemEventHandler(fsw_Created);
            fsw.EnableRaisingEvents = true;
            Console.ReadLine();
        }

        static void fsw_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("{0} was created", e.FullPath);
        }

        static void fsw_Renamed(object sender, RenamedEventArgs e)
        {
            Console.WriteLine("{0} was Renamed", e.FullPath);
        }

        static void fsw_Deleted(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("{0} was Deleted", e.FullPath);
        }

        static void fsw_Changed(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("{0} was Changed", e.FullPath);
        }
}
pablito
+2  A: 

To all who responded with, use FileSystemWatcher, how do you deal with the time your app isn't running? For example, the user has rebooted the box, modified the file you are interested in, and then starts up your app?

Be sure to also read the docs on FileSystemWatcher Class carefully specially the section about Events and Buffer Sizes.

Ants
They wanted a .Net solution. This could be implemented in a service that auto-starts, or a systray app that auto-starts etc. It's up to the OP to research further, but this will get them started.
ck
+1  A: 

You're likely to run into issues with FileSystemWatcher (not getting events, too many events, etc.) This code wraps it up and solves many of them: http://precisionsoftware.blogspot.com/2009/05/filesystemwatcher-done-right.html

Eric