问题
I have the following sub:
Private Sub Watcher_Changed(ByVal sender As System.Object, ByVal e As FileSystemEventArgs)
If Path.GetExtension(e.Name) = ".p2p" Then
Exit Sub
Else
Try
' multiple change events can be thrown. Check that file hasn't already been moved.
While Not File.Exists(e.FullPath)
Exit Try
End While
' throw further processing to a BackGroundWorker
ChangedFullPath = e.FullPath
ChangedFileName = e.Name
FileMover = New BackgroundWorker
AddHandler FileMover.DoWork, New DoWorkEventHandler(AddressOf ProcessFile)
FileMover.RunWorkerAsync()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End Sub
I'm still getting multiple changed-file notifications when a file is being uploaded by FTP.
I want to modify the Try so it also throws out the change notification if it has happened within the past (time) -- let's say 3 seconds. It ought to be trivial, but for some reason it isn't coming to me today, and my mind isn't wrapping itself around the answers I'm finding on Google.
Thanks, Scott
回答1:
I created a service to upload files dumped to an FTP folder a couple years ago and here's some things I did that should help you get over your problem:
- I tested all the NotifyFilters and chose the one that cut out duplicate notifications (using only NotifyFilters.Size gave me reliable notifications for every file created, and eliminated nearly all duplicate notifications)
- In the Watcher_Changed event I ignored the file included in the event args and just processed all files currently in the folder; I try to add all files in the folder to a queue, and if they're already in the queue, I skip 3 below.
- I spin off a new thread for every unique new file found; my thread tries to acquire a lock on the file, and if it can't that means some other process is still accessing it (it's still being uploaded, etc.) so my thread sleeps and tries again after a short interval.
- When a file is completely processed, the last thing the thread does is move it to an archive folder, and then remove it from the queue, so it isn't accidentally processed again.
This seemed to work out for me and that service ran reliably uploading files for months until I left that job.
回答2:
we had a similar situation; however the system that wrote the file in batches used a temp name, and changed it to the "real" name when it was done. Can your ftp client do something similar? If it can, then you can check the new filename and check it by extension or a prefix; if its not the expected final filename format then you can ignore it.
回答3:
I ran into the exact situation before, and ended up implementing a timer mechanism to wait for the file to "settle", or for write events to stop coming in for x amount of time.
A bit kludgy, but it worked.
回答4:
One thing to note is that accessing the file can change one of the file properties, like "accessed time" or something. That can then fire off another event if you don't have the notification filters setup right.
回答5:
I had this same issue, I was saving a file that was uploaded through code and deleting and creating would fire twice each time. All I had to check was that the File was there before doing my processing.
private void fsw_Created(object sender, FileSystemEventArgs e)
{
if (File.Exists(e.FullPath))
{
//process the file here
}
}
回答6:
I had the same problem today while trying to automatically reload a configuration file on change. I ended up computing an MD5 hash of the file to figure out if the file had actually changed and only reloading if the hash was different. This was the only definitive way I could filter out duplicates.
I briefly thought about using a timer mechanism to filter out change notifications but felt, like pete-m, but I felt it was too unclean a solution.
I tried watching only for LastWrite time changes but that didn't work. I was still getting duplicate notifications.
回答7:
I'm trying to detect when an excel file changes but am running into a problem that the changed event is not firing and as Im only concern with a single file setting the filter doesnt work. When I remove the filter and look at an event that is triggered the event argument name property looks to be a random generated name and not the specific filename which I know has changed.
So I'm not able to get a simple notification when a specific excel file changes.
来源:https://stackoverflow.com/questions/381976/handling-multiple-change-events-in-filesystemwatcher