Problem with ReadDirectoryChangesW notifications

I'm watching changes in a folder using ReadDirectoryChangesW (http://msdn.microsoft.com/en-us/library/aa365465%28VS.85%29.aspx) with the FILE_NOTIFY_CHANGE_LAST_WRITE parameter.

When a file is modified my thread gets a FILE_NOTIFY_INFORMATION structure.

All works fine so far.

The problem: The event is sent several times, and I cannot distinguish between a file write in progress and a file write complete.

I watch the folder c:\temp

Example 1:

If I copy a file called testfile.txt (100 mb) with Windows Explorer to c:\temp

I get the  FILE_NOTIFY_INFORMATION 3 (!!) times in a row. 2 times in the moment the write operation starts and a third (!) time when the copy is completed after 5 seconds.

Example 2:

If I copy a file called testfile.txt (100 mb) with Total Commander (a file manager) to c:\temp

I get the  FILE_NOTIFY_INFORMATION 2t(!!) times in a row. First time in the moment the write operation starts and a second (!) time when the copy is completed after 5 seconds.

I want to know when the copy operation is completed, I have no interest in events when the copy operation starts.

How to distinguish it?

I cannot count the number of  FILE_NOTIFY_INFORMATION events, since I get one to three events with differnet programs making the file changes (e.g. one with drop box, two with total commander, three with windows explorer).

I've tried this as a solution:

I use GetFileSecurityW after an event to check if I have GENERIC_WRITE access rights to the file. The problem is that as administrator windows reports that I have write rights even during the copy operation, not only after it has been completed.

My code is in Delphi, but a solution in C++ will be also accepted.
ThomasReimannAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ThomasReimannAuthor Commented:
p.s.

Checking if the file is in use is also not a solution, since during the last  FILE_NOTIFY_INFORMATION, the file IS still n use.
0
jkrCommented:
Hm, maybe the example at http://www.codeproject.com/KB/files/directorychangewatcher.aspx ("CDirectoryChangeWatcher - ReadDirectoryChangesW all wrapped up") can shed in some light (I was actually looking for 'fwatch', but MSDN does not provide the code online any longer: http://msdn.microsoft.com/en-us/library/aa230342%28VS.60%29.aspx)
0
ThomasReimannAuthor Commented:
The example is doing the exact same thing I'm doing.

I don't think i have a bug in my code, ReadDirectoryChangesW apparently does not provide something like an FILE_WRITE_COMPLETED event, so I'm looking for a replacement.
0
itsmeandnobodyelseCommented:
>>>> ReadDirectoryChangesW apparently does not provide something like an FILE_WRITE_COMPLETED event

When a write was detected by the OS it cannot decide whether it was the last write. It also cannot watch for EOF write cause in case of updating or rewinding a file, no EOF was written. So, the only chance would be to watch for the file being closed. BUT, that way you wouldn't be notified for files which were not explicitly closed (e. g. log files or some file handles may be freed only at shutdown) or you might be notified deferred (e. g. if the close happened in a destructor).

MSDN writes about the event you used:
----------------------------------------------------------------------
FILE_NOTIFY_CHANGE_LAST_WRITE Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
----------------------------------------------------------------------

That means file flushing actually is the event you were notified of. The filetime will change for any flush cause the unit is nanoseconds.

That means that 'file completion' actually isn't a status that can be well-defined. When a logfile written from two or more processes was completed?

So, I would store the notifications in a way that I could check for multiple notifications. I additional would check on the FILE_NOTIFY_CHANGE_FILE_NAME event which would allow to track on actions like renaming, creating and deleting files. Then you could periodically - say any minute - check whether operations on one file were probably completed: for example the criteria could be that there was no further notification within the last period, or that the file size, file times didn't change for some period.
 
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.