Reputation: 97
In a project I have a working folder. If we copy files or folders of files from somewhere to this folder, I need to detect if the copying has been finished or not. After that I'd handle the files in this working folder.
FileSystemWatcher theWatcher = new FileSystemWatcher(workingFolder);
theWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
NotifyFilters.FileName | NotifyFilters.DirectoryName |
NotifyFilters.Size;
theWatcher.IncludeSubdirectories = true;
theWatcher.Created += OnFolderChanged;
theWatcher.EnableRaisingEvents = true;
Whenever a file is copying, OnFolderChanged event will be triggered. So at first I tried to get the eclipse time between 2 file copying, but the eclipse time is very hard to determine due to network speed and file size. I also tried the method in Find if a Copy process is in progress on Directory, but the token file still can be opened when copying is in process.
Any good way to handle this?
Upvotes: 3
Views: 2297
Reputation: 942267
You cannot possibly reverse-engineer the operation of a process you know nothing about with FileSystemWatcher. There are many possible failure modes. A good example would be the user using Explorer to copy the files and it showing a dialog because the destination file already exists. With the user off taking a bathroom break since he counted on it taking a while.
You should never make any assumptions about what is going on. Arbitrarily, start a one minute timer when you get a notification and restart it when you get another one. When the timer ticks then you have some reason to guess that the copy operation is complete. Just make sure that it is never a problem when you guessed wrong.
Upvotes: 2
Reputation: 2741
If you have control over the process that is copying the file/folder - you could append a suffix (.complete) to the file/folder when it's finished copying and set-up the file system watcher to only respond to files/folders that have the .complete extension.
Update - Since you don't have control over the copied file/folder names - I would use exception handling in the FolderChaged
method. I assume that you're doing some processing with the file/folder in that method and that, when you attempt to access a file/folder that's not finished copying - you'll get some kind of System.IO
exception.
I've run into this problem with the FSW as well and I've handled it by catching the exception, pausing for a few seconds, and then trying to access the file again. I put this logic in a loop that would retry accessing the file 5 times over 10 seconds. If we still can't process the file after 5 tries - we throw the exception and our standard error handling takes over.
Of course, it's still an open question of what the appropriate looping parameters are for you and, if you hit the limit of those parameters, how do you handle the failure?
Upvotes: 0