Ich versuche, eine Datei zu erstellen, und vorher löschen Sie, wenn es existiert. Mein Problem ist, dass, wenn ich einen erfolgreichen Löschvorgang habe und sofort danach versuche, den gleichen Ordner zu erstellen, es mit AccessDenied fehlschlägt. Die Methodenbeschreibung (sowohl für deleteIfExists als auch für createDirectory) erwähnt solch ein Verhalten nicht, also denke ich, dass ich etwas falsch mache.Der Versuch, ein Verzeichnis sofort nach einem erfolgreichen zu erstellen deleteIfExists löst AccessDenied Exception
Dies ist der Code:
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();
}
}
}
So in einem erfolgreichen Lauf (wenn kein Lösch ist). dies ist der Ausgang
It does not exist, no need to delete anything
Creating alphaCpy nio2\alphacpy
copying inner.txt to the new directory nio2\alphacpy\inner.txt
Wenn ich es danach ausgeführt werden, wenn die Ordner und die Datei bereits vorhandenen i die Ausnahme erhalten:
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)
nächster Lauf ist wieder erfolgreich, da es bereits gelöscht wurde und bald. Die Frage ist also, was die AccessDenied-Ausnahme verursacht? Bedenken Sie, dass die Datei nicht geöffnet/verwendet wird und die relativen Pfade gültig sind.
EDIT: Ok ich schaffte es zu korrigieren, aber ehrlich gesagt kann ich mir immer noch nicht das ursprüngliche Problem erklären. Also werde ich dankbar sein, wenn jemand damit helfen kann. Ich ging von der Verwendung eines Streams zu Datei [], um die Datei in dem Ordner zu löschen. Nachdem ich das gemacht habe, funktioniert es wie ein Zauber. Hier
ist der korrigierte Code:
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());
}
}
Offensichtlich sind die Stream-Operationen halten sie gesperrt irgendwie, auch nach Abschluss, aber dies ist kein IO-Stream (oder ist es mit files.list() ??) dass ich schließen kann, also was kann ich tun, um es mit Stream arbeiten zu lassen - es ist nicht etwas, das verschließbar ist oder etwas, das versucht GC zu erzwingen, macht Sinn.
Wenn Sie durch den Code eine Zeile nach dem anderen in Ihrem Debugger sehen Sie immer noch den gleichen Fehler? Wenn dies nicht der Fall ist, kann die Löschoperation zurückkehren, sobald das Löschen vom Betriebssystem akzeptiert wird, aber das Betriebssystem benötigt eine endliche Zeit (zehn bis hundert Millisekunden), um das Löschen des Verzeichnisses abzuschließen. Wenn dies der Fall ist, müssen Sie eine Wiederholungsschleife mit exponentiellem Backoff bis etwa 1 Sekunde einfügen. Sie können den Vorgang nicht unbegrenzt wiederholen, da möglicherweise eine Bedingung für den Zugriff verweigert wurde. –
Gleiches Ergebnis im Debugger Schritt für Schritt. Auch versucht mit dem Hinzufügen von Thread.sleep (5000); , so dass der Haupt-Thread nach dem Löschen einige Sekunden wartet. Keine Änderung der Ergebnisse. –
Warum verwenden Sie doppelte _forward_ Schrägstriche. Du solltest das nicht tun. Versuchen Sie einzelne Schrägstriche. Drucken Sie auch den Wert von 'Files.exists (target)' nach dem Löschvorgang, um zu sehen, was der NIO-Stapel über das Vorhandensein des Verzeichnisses denkt. –