Files#delete(Path)和File#delete()之间的区别

22

我使用安装有Java 7更新6的Windows-7,发现了一个奇怪的(至少对我来说是)行为 -
我有两个文件E:\delete1.txtE:\delete2.txt,它们都是只读文件。当我尝试像下面这样删除文件时,它会被轻松删除 -

File file = new File("E:\\delete1.txt"); 
assertTrue(file.delete());

但是当我使用nio API删除文件时,如下所示 -

Path path = Paths.get("E:\\delete2.txt");
Files.delete(path);

它抛出了java.nio.file.AccessDeniedException

为什么旧的和新的nio API执行相同操作时会有不同的行为?


如果您交换文件,即NIO API删除delete1.txt而旧API File删除delete2.txt会发生什么? - David Kroukamp
2
@MichaelBorgwardt 为什么奇怪?他只是试图删除一个文件(恰好是只读的) - assylias
@assylias:无论怪不怪,这肯定是一个边缘案例。 - Michael Borgwardt
@MichaelBorgwardt,那你是在说同样的功能可以有不一致的行为,这样也没关系吗?如果是这样的话,nio就不能真正取代File API。如果它是不一致的,那么其中一种实现一定是正确的,而另一种则是错误的。 - Premraj
这不是“可以或不可以”的问题,而是不可避免的,除非有一个官方API,明确定义了两个实现都要明确声明实现,但在这种情况下并非如此。 - Michael Borgwardt
从Files.delete的规范中可以看到:“在某些操作系统上,当文件被Java虚拟机或其他程序打开并使用时,可能无法删除该文件。”有人能否在另一个操作系统上测试这种行为(我现在只有Windows)? - joergl
2个回答

22

正如在这里所讨论的那样 - 问题在于java.io.File在Windows中有很多奇怪的问题。在这种情况下,它会在删除文件之前重置文件属性,因此不会像预期的那样失败。这是一个已经存在超过10年的行为,所以现在更改可能存在风险。它还有其他几个类似的奇怪问题,这也是为什么它没有被重新实现使用新API的原因之一。

如果我们尝试从命令窗口删除文件,则Windows会抛出相同的(访问被拒绝)错误,但从资源管理器窗口中可以删除文件。看起来File#delete()有一个错误的实现,应该优先使用新的Files#delete(Path)


4
请问您需要的翻译是:“能否对File#delete()具体有哪些问题进行更详细的解释?” - ZX9

2
为什么旧版和新版nio API执行相同操作的行为不同?
因为在设计新API时,精确模拟旧API类似操作的行为显然不是一个重要目标。考虑到nio文件系统API的主要目标是提供一个全新的API,具有一些完全不同的基本概念和许多新功能,这对我来说似乎很正常。

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