java - 尝试在成功 deleteIfExists 后立即创建目录引发 AccessDenied 异常

标签 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());
        }

    }

显然,即使在完成后,流操作也会以某种方式保持锁定状态,但这不是我可以关闭的 IO 流(或者它是否与 Files.list()??),那么我该怎么做才能使其工作with Stream - 它不是可关闭的东西,也不是试图强制 GC 的东西。

最佳答案

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

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

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

关于java - 尝试在成功 deleteIfExists 后立即创建目录引发 AccessDenied 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39628328/

相关文章:

c# - 安全删除目录

java - 如果使用 Files.find(),则出现 AccessDeniedException

javascript - jQuery "Access Is Denied"错误

java - 如何在 java 中使用特定规则对给定字符串进行子字符串化

PHP Delete 返回错误

java - Hector - 使用复合键插入行

c# - System.IO.File.Delete()/System.IO.File.Move() 有时不起作用

windows - 管理员帐户访问 Windows 7 上的文件被拒绝

一元前缀运算符的 Java 消歧

java - 有没有办法将 Key 存储在我从 Firebase 对象转换的类中?