DirectoryStream 的文档清楚地指出:
迭代器是弱一致的。它是线程安全的,但在迭代时不会冻结目录,因此它可能(也可能不会)反映在 DirectoryStream 创建后发生的对目录的更新。
在我的机器上,我在调试模式下对目录执行了简单的迭代。在迭代完成之前,我中断了执行,将一个文件添加到正在迭代和恢复的目录中。迭代没有看到额外的文件。
我的问题:在什么情况下迭代会反映目录内容的更新?不幸的是,正式的文档对此非常模糊。至少可以说。
DirectoryStream 的文档清楚地指出:
迭代器是弱一致的。它是线程安全的,但在迭代时不会冻结目录,因此它可能(也可能不会)反映在 DirectoryStream 创建后发生的对目录的更新。
在我的机器上,我在调试模式下对目录执行了简单的迭代。在迭代完成之前,我中断了执行,将一个文件添加到正在迭代和恢复的目录中。迭代没有看到额外的文件。
我的问题:在什么情况下迭代会反映目录内容的更新?不幸的是,正式的文档对此非常模糊。至少可以说。
文档故意含糊不清。JVM 必须在多种不同类型的机器上运行:Windows 和 Unix 衍生产品。不同的文件系统有不同的行为。如果您希望您的程序在多台计算机上可靠地工作,您必须(我重复一遍,必须)设计最坏的情况。
最不意外法则建议您应该吞食整个 DirectoryStream 以获得快照(或非常接近快照),迭代快照,然后重新吞食流。然后,您可以比较不同版本的快照以确定对基础目录的更改。
作为DirectoryStream
一个接口,并且由于 NIO.2 的这一部分旨在可插入,因此不要将您的考虑限制在 JDK 随附的 Linux 和 Windows 实现上。完全有可能编写具有该行为的自定义实现,或者对于集群或分布式实现具有该行为作为副作用。
该文档是故意含糊不清的,在 POSIX 下,它委托给readdir
它也是故意含糊的:
如果在最近一次调用 opendir() 或 rewinddir() 之后从目录中删除或添加文件,则未指定后续调用 readdir_r() 是否返回该文件的条目。
但是,如果您正在寻找一个实现依赖于这种模糊性的具体案例,那么Linux ext3 readdir 和并发更新会显示一个案例rsync
,在一个ext3
大容量的文件系统上,似乎看到文件出现在它们的顺序之外的目录中被创建于。