成功执行deleteIfExists后,尝试立即创建目录会抛出AccessDenied异常

时间:2016-09-22 00:12:40

标签: java delete-file access-denied

我正在尝试创建一个文件,在此之前删除它(如果存在)。我的问题是,每当我有一个成功的删除操作,并在此之后立即尝试创建相同的文件夹,它失败与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一起使用 - 它不是Closable或者试图强制GC的东西是有意义的。

1 个答案:

答案 0 :(得分:0)

我注意到程序使用Files.list(dir)后跟Files.deleteIfExists(path)的类似问题。在VM退出之前,所有已删除的文件夹都不会从Windows资源管理器视图中消失,并且如果在Windows资源管理器中单击,直到VM退出时,将拒绝访问。

我的程序只是通过在使用后关闭每个Files.list()流来修复,最好是使用try(resource)... finally。然后,Windows资源管理器会立即与每次删除同步,而不是等到VM退出

try(Stream<Path> str = Files.list(target))
{
    // do your str.forEach() calls with Files.deleteIfExists
}
finally
{
}