您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用Files.delete()删除文件时的奇怪行为

使用Files.delete()删除文件时的奇怪行为

打开文件删除文件的目录条目是完全有效的。在Unix中,这是认的语义,并且WindowsFILE_SHARE_DELETE在打开该文件的所有文件句柄上进行设置时的行为类似。

[编辑:感谢@couling的讨论和更正]

但是,两者之间存在细微的差别:Unix ,而Windows 。但是,它会阻止您打开具有相同名称文件,直到关闭(已删除文件的最后一个句柄为止。

去搞清楚 …

但是,在两个系统上,删除文件并不一定会使文件消失,只要仍然有打开的句柄,它仍会占用磁盘上的空间。仅在最后一个打开的句柄关闭时才释放文件占用的空间。

在Windows上必须指定该标志,这使大多数人似乎Windows无法删除打开的文件,但实际上并非如此。这只是 行为。

CreateFile()

文件或设备上启用后续打开操作以请求删除访问。

否则,如果其他进程请求删除访问,则它们将无法打开文件或设备。

如果未指定此标志,但是已打开文件或设备以进行删除访问,则该功能将失败。注意删除访问权限允许删除重命名操作。

DeleteFile()

DeleteFile函数关闭时将文件标记为要删除。因此,在关闭文件的最后一个句柄之前,不会发生文件删除。随后调用CreateFile打开文件失败,并显示ERROR_ACCESS_DENIED。

打开没有名称文件的句柄是创建未命名临时文件的最典型方法之一:创建一个文件,打开它,然后删除文件。现在,您可以处理其他人无法打开的文件。在Unix上,文件名确实消失了,在Windows上,您无法打开具有相同名称文件

现在的问题是:

查看源代码,您可以看到shareDelete确实认为true。重置它的唯一方法是使用非标准ExtendedOpenOptionNOSHARE_DELETE

因此,是的,您可以删除Java中打开的文件,除非它们被明确锁定。

DeleteFile()上面的文档中隐藏了答案:该文件标记删除,该文件仍然存在。在Windows上,只有 正确 删除文件(即关闭文件的所有句柄)后,才能使用标记删除文件 创建文件。 __

Windows混用名称删除和实际文件删除的可能混淆可能是Windows首先不允许认情况下删除打开文件的原因。

Files.exists()在Windows的最深层中 。

详细来说:Java代码调用@L_403_5@)不带参数,该调用WindowsFileSystemProvider.checkReadAccess()立即尝试打开文件,因此失败。据我所知,这是您致电时采取的路径Files.exist()

还有另一个代码路径调用GetFileAttributeEx()来检索文件属性。再次没有记载,当您尝试检索删除但尚未删除 文件属性时会发生什么,但是实际上,您无法检索 标记删除文件文件属性

猜猜,我会说在某个时候GetFileAttributeEx()调用GetFileInformationByHandle(),它将永远不会到达,因为它首先无法获得文件句柄。

确实如此,在DeleteFile()文件出于大多数实际目的而消失之后。它仍然有一个名称,但是会显示在目录列表中,并且在原始文件的所有句柄都关闭之前,您无法打开具有相同名称文件

这种行为或多或少是一致的,因为GetFileAttributes()用于检查文件是否存在实际上是 文件可访问性 检查,它被解释为 文件存在FindFirstFile()(由Windows资源管理器用于确定文件列表)查找文件名, 但不告诉您有关文件 名的 可访问 性。

欢迎您再来几个怪异的循环。

SQL 2022/1/1 18:14:19 有447人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶