Windows 上有类似 inotify 的东西吗?

119

在Linux操作系统中,有一个名为inotify的子系统,它可以通知应用程序文件系统的变化。

然而,我主要使用Windows系统,所以我想知道是否有类似的方法来监视文件系统的变化?


9
我认为这类问题并不属于离题。该问题询问的是一个操作系统API,它与任何工具/软件库都有很大的区别。也许可以换一种说法,比如当特定文件/文件被修改时,在Windows应用程序中如何获得通知。 - balki
1
投票重新开放:该问题正在寻求一个类似的替代方案来替换特定的操作系统API,对我来说这个问题比喻地读起来像是“我来自英国,在那里我用叉子吃饭,那么在日本我应该使用什么样的餐具?”使用这个比喻的被接受答案是“使用筷子”。 - David
8个回答

50

如果你在使用.net,请使用FileSystemWatcher。更多信息请参见:http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

如果你在使用C,请使用FindFirstChangeNotificationFindNextChangeNotificationReadDirectoryChangesW。更多信息请参见:http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx

OSX上,相关的api是fsevents api。

它们都有微妙的差别,并且在边缘情况下它们的可靠性都具有疑问。一般来说,你不能完全依赖这些api始终100%地查看所有的变化。大多数使用文件系统监控的人会与定期扫描结合使用,以补偿由于推送api丢失或不完整而导致的信息缺失。


7
请问您能否提供一些关于“inotify 在极端情况下可靠性有问题”的引用? - Pharaun
20
如果一个文件系统监视器API的消费者读取事件的速度比其他进程生成事件的速度慢,内核要么需要阻塞其他(可能优先级更高)进程中的文件系统修改,要么允许缓冲区无限增长。inotify的缓冲深度(如man手册所述)由/proc/sys/fs/inotify/max_queued_events控制。超过这个值,你会收到IN_Q_OVERFLOW通知 - 这是好的,但你仍然需要不时地重新扫描。 - blucz
啊哈,我最近在研究队列。我认为这种边缘情况取决于你监视的文件数量,还取决于是否需要跟踪所有更改,或者可以忽略一些更改。但这是一个好观点。谢谢 :) - Pharaun
1
@blucz 我自己也在想内核人员是如何解决这些情况的。知道他们这样做,让人在设计和实现时更有信心。 - n611x007

38


11
有点晚了,但是… Windows 有一个类似于 OSX 事件的设施,可以在不运行应用程序的情况下监视事件。Windows USN 日志跟踪所有文件更改。 Jeffrey Richter(《高级 Windows》的作者)为 MSDN Journal 写了一篇带有工作示例的精彩文章更新自从 MSJ 不再在 MS 上线后,该文章现在来自 archive.org。 USN 更改日志的 MSDN 文档。 如果您正在构建像备份工具或需要监视整个卷的索引这样的应用程序,则 USN 更改日志可能更好。

USN日志的方式是否有所不同,依赖它是否可以避免FileSystemWatcher|FindFirstChangeNotification的错误行为?这是PhillipBrandonHolmes此处所提到的吗? - n611x007
4
我很久以前做过这个,但是它没有使用FileSystemWatcher或FindFirstChangeNotification。我开始用Go语言编写Windows事件监视器,很大程度上基于Jeffery Richter的示例。从我所做的一些测试来看,它非常可靠,没有遗漏任何内容,类似于OS X中的fsevents。Gist在这里:https://gist.github.com/pkrnjevic/7219861 - Peter Krnjevic
@PeterKrnjevic,你能更新一下 Jeffrey Richter 文章的链接吗? - SOUser
@SOUser,由于微软的位腐败问题,该文章现在已经从archive.org链接。 - Peter Krnjevic

11

8
JNotify非常适合我,因为我需要跨平台兼容性。我甚至能够编写一段单一的bash脚本,在cygwin、mac和linux上运行,只要JAVA_HOME设置正确。这对于在客户机器上调试问题时非常有帮助,当他们说“它删除了我的文件!”时,我可以查看日志并尝试找出是什么时候发生的。 - cmyers
1
FileMon现在更名为ProcessMonitor。https://technet.microsoft.com/zh-cn/sysinternals/bb896645 - MECU

4

FileSystemWatcher()不太可靠,主要是因为其用于监视缓冲区的错误处理更或者更不完整。由于缺乏路径和详细的错误处理信息,Microsoft没有提供任何恢复或手动轮询工作目录的方法。

JNotify for Windows也不太可靠,因为这个bug源于win32。JNotify使用win32。因此,它与FileSystemWatcher()没有什么不同。


考虑如何设计角色来解决这种类似于“速度”、“竞赛”或“溢出”的问题,我想知道内核是如何解决的。很有意思。网络和日志记录也会遇到这个问题。这个问题有一个名称吗? - n611x007
是的,它的名字叫做“bug”。这个漏洞(win32)已经存在于微软创建的每个操作系统中。这使得任何微软操作系统都不适合于文件监视类型的解决方案。你必须去*nix才能完成它。有时我认为他们故意留下这个缓冲区溢出以确保安全性。 - Phillip Holmes
哈哈,是的,它的名字叫做意图混乱集群(intentional cluster kludge),这样微软的文件系统就不能被有意地监视。这是由于安全问题而留下的漏洞。 - Phillip Holmes

1

我做了一些搜索,我似乎记得在Windows上看到过类似的东西。对于.NET,有FileSystemWatcher。它主要适用于NT或XP及以上版本。


2
它更普遍地只能在NTFS文件系统上使用,但不能在FAT16、FAT32甚至新的exFAT上使用。 - Mastacheata

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接