打开文件时删除文件的目录条目是完全有效的。在Unix中,这是默认的语义,并且WindowsFILE_SHARE_DELETE
在打开该文件的所有文件句柄上进行设置时的行为类似。
[编辑:感谢@couling的讨论和更正]
但是,两者之间存在细微的差别:Unix ,而Windows 。但是,它会阻止您打开具有相同名称的文件,直到关闭(已删除)文件的最后一个句柄为止。
去搞清楚 …
但是,在两个系统上,删除文件并不一定会使文件消失,只要仍然有打开的句柄,它仍会占用磁盘上的空间。仅在最后一个打开的句柄关闭时才释放文件占用的空间。
在Windows上必须指定该标志,这使大多数人似乎Windows无法删除打开的文件,但实际上并非如此。这只是 默认 行为。
否则,如果其他进程请求删除访问,则它们将无法打开文件或设备。
如果未指定此标志,但是已打开文件或设备以进行删除访问,则该功能将失败。注意删除访问权限允许删除和重命名操作。
DeleteFile函数在关闭时将文件标记为要删除。因此,在关闭文件的最后一个句柄之前,不会发生文件删除。随后调用CreateFile打开文件失败,并显示ERROR_ACCESS_DENIED。
打开没有名称的文件的句柄是创建未命名临时文件的最典型方法之一:创建一个新文件,打开它,然后删除该文件。现在,您可以处理其他人无法打开的文件。在Unix上,文件名确实消失了,在Windows上,您无法打开具有相同名称的文件。
现在的问题是:
查看源代码,您可以看到shareDelete
确实默认为true
。重置它的唯一方法是使用非标准ExtendedOpenOption
NOSHARE_DELETE
。
因此,是的,您可以删除Java中打开的文件,除非它们被明确锁定。
DeleteFile()
上面的文档中隐藏了答案:该文件仅标记为删除,该文件仍然存在。在Windows上,只有 正确 删除文件(即关闭文件的所有句柄)后,才能使用标记为删除的文件 名 创建文件。 __
Windows混用名称删除和实际文件删除的可能混淆可能是Windows首先不允许默认情况下删除打开文件的原因。
Files.exists()
在Windows的最深层中 。
详细来说:Java代码调用@L_403_5@)不带参数,该调用WindowsFileSystemProvider.checkReadAccess()
立即尝试打开文件,因此失败。据我所知,这是您致电时采取的路径Files.exist()
。
还有另一个代码路径调用GetFileAttributeEx()
来检索文件属性。再次没有记载,当您尝试检索已删除但尚未删除的 文件的属性时会发生什么,但是实际上,您无法检索 标记为删除 的文件的文件属性。
猜猜,我会说在某个时候GetFileAttributeEx()
调用GetFileInformationByHandle()
,它将永远不会到达,因为它首先无法获得文件句柄。
确实如此,在DeleteFile()
文件出于大多数实际目的而消失之后。它仍然有一个名称,但是会显示在目录列表中,并且在原始文件的所有句柄都关闭之前,您无法打开具有相同名称的文件。
这种行为或多或少是一致的,因为GetFileAttributes()
用于检查文件是否存在实际上是 文件可访问性 检查,它被解释为 文件存在 。FindFirstFile()
(由Windows资源管理器用于确定文件列表)查找文件名, 但不告诉您有关文件 名的 可访问 性。
欢迎您再来几个怪异的循环。