我正在开发一段 C 代码,它使用 ReadDirectoryChangesW() 来监视 Windows 目录下的更改。我已经阅读了 ReadDirectoryChangesW() 和 FILE_NOTIFY_INFORMATION 结构的相关 MSDN 条目,以及其他几篇文档。在这一点上,我已经设法监控多个目录,监控本身没有明显问题。问题是这个函数放在 FILE_NOTIFY_INFORMATION 结构中的文件名不是规范的。
根据 MSDN,它们可以是长形式或短形式。我发现了几篇建议缓存短路径名和长路径名来处理这种情况的帖子。不幸的是,根据我自己在 Windows 7 系统上的测试,这不足以消除该问题,因为每个文件名不仅有两种选择。问题是路径名中的每个组件都可以是长格式或短格式。以下路径名都可以引用同一个文件:
c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT
c:\PROGRA~1\MYPROG~1\MyDataFile.txt
c:\PROGRA~1\MyProgram\MYDATA~1.TXT
c:\PROGRA~1\MyProgram\MyDataFile.txt
c:\Program Files\MYPROG~1\MYDATA~1.TXT
...
据我使用 cmd.exe 进行的测试可以看出,它们都是完全可以接受的。本质上,每个文件的有效路径名的数量随着其路径名中的组件数量呈指数增长。
不幸的是,ReadDirectoryChangesW() 似乎用提供给导致每个操作的系统调用的文件名填充其输出缓冲区。例如,如果您使用 cmd.exe 命令来创建、重命名、删除等文件,则 FILE_NOTIFY_INFORMATION 将包含在命令行中指定的文件名。
现在,在大多数情况下,我可以使用 GetLongPathName() 和朋友来获得一条独特的路径供我使用。不幸的是,删除文件时无法做到这一点——当我收到通知时,文件已经消失,Get*PathName() 函数将无法工作。
目前我正在考虑使用更广泛的缓存来确定每个文件的应用程序使用哪些替代路径名,这将处理任何情况,除了有人决定使用看不见的混合路径名突然删除文件的情况. 而且我正在考虑从父目录修改事件中进行创造性数据挖掘,并回退到检查该案例的实际目录。
关于更简单的方法的任何建议?
PS1:虽然 Change Journals 可以有效地处理这个问题(我希望),但由于它们与 NTFS 的联系以及我的应用程序缺乏管理员权限,我不相信我可以使用它们。我宁愿不去那里,除非我绝对被迫去。
PS2:请记住,我主要在 Unix 上编码,所以要温柔...