views:

103

answers:

2

Other than reading all the files and comparing them with a previous snapshot, is there a way to detect when a directory changes in C# with Windows? I don't mind PInvoke if that's what it takes.

+12  A: 

Use the FileSystemWatcher class - it does what you want. It won't tell you which bytes in the file changed, but it will tell you which files have changes.

From the doc:

Use FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and subdirectories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.

To watch for changes in all files, set the Filter property to an empty string ("") or use wildcards ("."). To watch a specific file, set the Filter property to the file name. For example, to watch for changes in the file MyDoc.txt, set the Filter property to "MyDoc.txt". You can also watch for changes in a certain type of file. For example, to watch for changes in text files, set the Filter property to "*.txt".

There are several types of changes you can watch for in a directory or file. For example, you can watch for changes in Attributes, the LastWrite date and time, or the Size of files or directories. This is done by setting the NotifyFilter property to one of the NotifyFilters values. For more information on the type of changes you can watch, see NotifyFilters.

You can watch for renaming, deletion, or creation of files or directories. For example, to watch for renaming of text files, set the Filter property to "*.txt" and call the WaitForChanged method with a Renamed specified for its parameter.

LBushkin
it will USUALLY tell you which files have changes. I've tested the thing. Under heavy load its not 100%.
P.Brian.Mackey
there are also a lot of "gotchas" to watch out for in the implementation. Make sure you read all the documentation thoroughly. You may have to reinitialize the watcher from time to time when an error happens.
Garo Yeriazarian
Brilliant, thanks!
John JJ Curtis
+1  A: 

I've had to do this for a program that would watch a directory and see if any new image files were added, and it would then automatically resize them. When someone would add multiple files at one time, the watcher wouldn't catch all the files since it was single threaded and was busy resizing one image while another was being dropped.

I had to make this a multi-threaded app, where the main thread just watched the directory and added the files to a queue, and another thread would read from the queue and resize those images.

That's something you might want to be careful of if you're going to be doing anything with the files.

Makotosan
Yes, I will definitely spawn a thread pool thread for each file operation I will be doing, thanks for the tip!
John JJ Curtis