
文章说明:当 Windows 的 ReadDirectoryChangesW 报告某个文件或目录已被删除时,该对象通常已经不存在,系统也无法再提供更多属性信息。若应用在删除事件发生后仍需了解被删对象的详细资料,就必须在其尚存在时自行缓存或记录这些信息。
A customer was using ReadDirectoryChangesW to monitor changes to a directory. However, they ran into a problem when they received a FILE_ACTION_REMOVED notification: Since the notification is raised when the item is deleted, they can’t do a GetFileAttributesEx to find out whether the deleted item was a file or a subdirectory, and if it was a file, the size of the deleted file. Their program needs that information as part of its directory monitoring, so what mechanism is there to recover that information?
The ReadDirectoryChangesW function provides no way to recover information about the item that was deleted. All you get is the name of the item.
Recall that ReadDirectoryChangesW is for detecting changes to information that would appear in a directory listing. The idea is that your program performs a FindFirstFile/FindNextFile to build an in-memory cache for a directory, and then you can use ReadDirectoryChangesW to perform incremental updates to your cache. For example, if you see a FILE_ACTION_ADDED, then you can call GetFileAttributes or GetFileAttributesEx to get information about the thing that was added and update your cache. That way, when you see the FILE_ACTION_REMOVED, you can read the entry from your cache to get the information about the item that was removed (as well as removing it from your cache).
There is a race condition here, however. If the item is added and then immediately deleted, then when you get around to calling GetFileAttributes, it won’t be there, so you don’t actually know what it was.
Fortunately, there’s ReadDirectoryChangesExW. If you ask for ReadDirectoryNotifyExtendedInformation, then you get back a series of FILE_NOTIFY_EXTENDED_INFORMATION structures, and in addition to the action and the file name, those also contain directory information about the item, including its file attributes. This information is provided both on the add and on the remove, so you can just look at the FileAttributes on the FILE_ACTION_REMOVED to see whether it was a file or a folder, and if it was a file, you can use the FileSize to see the logical size of the file at the time it was deleted.
Category
Topics
Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.