C# Detect file moves trough different folders
I want to detect every filechanges on a specific folder (except data changes). I decided to use System.IO.FileSystemWatcher to manage that.
//
// fileSysWatchFile
//
this.fileSysWatchFile.EnableRaisingEvents = true;
this.fileSysWatchFile.IncludeSubdirectories = true;
this.fileSysWatchFile.NotifyFilter = System.IO.NotifyFilters.FileName;
this.fileSysWatchFile.SynchronizingObject = this;
this.fileSysWatchFile.Created += new System.IO.FileSystemEventHandler(this.fileSysWatchFile_Created);
this.fileSysWatchFile.Deleted += new System.IO.FileSystemEventHandler(this.fileSysWatchFile_Deleted);
this.fileSysWatchFile.Renamed += new System.IO.RenamedEventHandler(this.fileSysWatchFile_Renamed);
As far as good... New files are detected. File delete开发者_开发百科s are detected. File renames are detected.
When I move a file to a subfolder it detects first a file delete and then a new file create.
I'd expect that a move is the same as a rename except the path. Seems that it isn't. Can I detect file moves in a save way?
By the way... I only want to detect file changes and not directory changes.
Edit:
Additional Info why I have to detect moves and can't live with delete, create:
I want to replay the same changes on an other drive. If I get a delete first, I delete the shadow file. Then I get the create file event and the original file is already lost :-(.
So I have a drive A which is the watched drive... And a drive B which has files with the same filenames.
All file changes exept data changes should be replayed on drive B.
The File delete / File create functionality is what is behind a file move. It's similar to rename if you are just moving a file from a folder to a folder, but what about if moving a file from one disk to another, or moving a file between machines?
And, If I'm watching a specified folder, as long as the file is not there, it might as well have been deleted :)
If you are sure that you want to catch file moved "events" (from a watched folder to a watched subfolder), I would maintain a list of recently deleted files, and upon every file created event, check if the file is it that list, indicating a de facto file move.
You can use file system filter driver to track file rename operation. Actually, FS Filter is better approach, than FileSystemWatcher. FileSystemWatcher doesn't provide reliability and flexibility for certain cases (you can see the number of questions regarding FileSystemWatcher and it's glitches and limitations).
FS Filter lets you track the requests as soon as they reach the file system.
You can write your own filter driver, or use our CallbackFilter product.
It's not a real solution of the problem, but I managed to have a quick and dirty solution:
First I am buffering all events for a while (tested with 100ms but we will see how fast it can go).
If a event is 100ms in the buffer I check if there is a depending other event also in there. So for Delete I search all creates and for create I search all deletes.
If I find one I replace the two events with only one move event.
There are some riscs with this workarround:
1.) I can't say what comes first, delete or create. Seems that this is every time different
2.) If the delay is to short, the file is deleted and lost :-(
But as long as I have no better solution I have to live with this.
精彩评论