【发布时间】:2016-09-22 00:12:39
【问题描述】:
我正在尝试创建一个文件,如果存在,则在此之前将其删除。我的问题是,每当我成功删除操作并立即尝试创建相同的文件夹时,它都会因 AccessDenied 而失败。方法描述(对于 deleteIfExists 和 createDirectory)没有提到这种行为,所以我想我做错了什么。
这是代码:
package nio2;
import java.io.*;
import java.nio.file.*;
public class Test{
public static void main(String[] args)
{
Path existing = Paths.get("nio2//alpha//inner.txt"); // already existing
Path cpytarget = Paths.get("nio2//alphacpy//inner.txt"); // file to be created
Path target = Paths.get("nio2//alphacpy");//
try{
if(Files.exists(cpytarget))
{
Files.list(target).forEach(Test::WrappedDeleteIfExists); // deleting files inside folder
System.out.println("Deleting the directory if it exists - alphaCpy\t" + Files.deleteIfExists(target));//deleting
}
else
System.out.println("It does not exist, no need to delete anything");
System.out.println("Creating alphaCpy\t" + Files.createDirectory(target));//creating
System.out.println("copying inner.txt to the new directory\t" + Files.copy(existing,cpytarget));
}catch(IOException e)
{
e.printStackTrace();
}
}
public static void WrappedDeleteIfExists(Path in)
{
try{
System.out.println("Deleting files inside the folder\t" + Files.deleteIfExists(in));
}catch (IOException e)
{
e.printStackTrace();
}
}
}
所以在成功运行时(没有删除时)。这是输出
It does not exist, no need to delete anything
Creating alphaCpy nio2\alphacpy
copying inner.txt to the new directory nio2\alphacpy\inner.txt
如果我在文件夹和文件已经存在时运行它,我会得到异常:
Deleting files inside the folder true
Deleting the directory if it exists - alphaCpy true
java.nio.file.AccessDeniedException: nio2\alphacpy
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:504)
at java.nio.file.Files.createDirectory(Files.java:674)
at nio2.Test.main(Test.java:19)
下一次运行再次成功,因为它已经被删除等等。所以问题是导致 AccessDenied 异常的原因是什么?请记住,该文件未打开/未使用,并且相对路径有效。
编辑:好的,我设法纠正了它,但老实说,我仍然无法向自己解释最初的问题。因此,如果有人可以提供帮助,我将不胜感激。我从使用 Stream 转到 File[] 以删除文件夹内的文件。在我这样做之后,它就像一个魅力。
以下是更正后的代码:
public static void main(String[] args) throws InterruptedException
{
Path existing = Paths.get("E:/work/Java/Tests/alpha/inner.txt"); // already existing
Path cpytarget = Paths.get("E:/work/Java/Tests/alphacpy/inner.txt"); // file to be created
Path target = Paths.get("E:/work/Java/Tests/alphacpy");//
File fileTarget = new File("E:/work/Java/Tests/alphacpy");
try{
if(Files.exists(cpytarget))
{
WrappedDeleteIfExists(fileTarget.listFiles()); // CHANGED , no longer using Stream<Path> pipeline to go through the file list
// deleting files inside folder
System.out.println("Deleting the directory if it exists - alphaCpy\t" + Files.deleteIfExists(target));//deleting
}
else
System.out.println("It does not exist, no need to delete anything");
System.out.println(Files.exists(target));
System.out.println("Creating alphaCpy\t" + Files.createDirectory(target));//creating
System.out.println("copying inner.txt to the new directory\t" + Files.copy(existing,cpytarget));
}catch(IOException e)
{
e.printStackTrace();
}
}
// CHANGED - using File[] instead of Path
public static void WrappedDeleteIfExists(File[] in)
{
for(int i =0;i<in.length;i++)
{
System.out.println("Deleting files inside the folder\t" +in[i].delete());
}
}
显然,即使在完成之后,Stream 操作也会以某种方式将其锁定,但这不是我可以关闭的 IO 流(或者它与 Files.list() 一起使用??),所以我该怎么做才能关闭让它与 Stream 一起工作 - 它不是可关闭的东西或试图强制 GC 的东西是有意义的。
【问题讨论】:
-
如果您在调试器中一次单步执行代码,是否还会看到相同的错误?如果不是,则可能是删除操作在操作系统接受删除后立即返回,但操作系统需要有限的时间(数十到数百毫秒)才能完成目录的删除。如果是这种情况,您将不得不插入一个带有指数回退的重试循环,例如 1 秒。您不能无限期地重试,因为可能存在真正的访问被拒绝情况。
-
一步一步在调试器中得到相同的结果。还尝试添加 Thread.sleep(5000); ,以便主线程在删除后等待几秒钟。结果没有变化。
-
为什么要使用双 forward 斜杠。你不应该那样做。尝试单正斜杠。另外,在删除操作后打印出
Files.exists(target)的值,看看NIO栈对目录存在的看法。 -
我也试过了,它返回 false- 不存在。还尝试了单独的硬盘驱动器+ pc重启。谢谢你的斜线。 :)
-
我没主意了。您可以查看Java bug database
标签: java delete-file access-denied