java - Kan ikke fjerne tom mappe

Indlæg af Hanne Mølgaard Plasc

Problem



I en eksisterende mappe oprettede jeg en mappe og indeholdt i flere filer ved hjælp af denne metode:


SeekableByteChannel createFile(String filePathToCreate) throws IOException {
    OpenOption[] options = {
            StandardOpenOption.WRITE,
            StandardOpenOption.CREATE\_NEW,
            StandardOpenOption.SPARSE,
            StandardOpenOption.READ
            // TODO: think if we add CREATE if exist rule.
    };
    return Files.newByteChannel(Paths.get(filePathToCreate), options);
}


Mapperne/filer strukturen er:


- torrents-test
   - folder1
       - File-I-Created-1
       - File-I-Created-2
       - File-I-Created-3


Så forsøgte jeg at slette mappen torrents-test ved hjælp af denne metode:


void deleteDirectory(File directoryToBeDeleted) throws IOException {
    File[] allContents = directoryToBeDeleted.listFiles();
    if (allContents != null) {
        for (File file : allContents) {
            deleteDirectory(file);
        }
    }
    Files.delete(directoryToBeDeleted.toPath());
}


Så fik jeg en undtagelse, som fortæller mig, at mappen folder1 ikke er tom, så jeg ikke kan slette den:


java.nio.file.DirectoryNotEmptyException: C:GITuniversity	orrentx	orrents-testfolder1
    at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:266)
    at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
    at java.nio.file.Files.delete(Files.java:1126)
    at com.utils.Utils.deleteDirectory(Utils.java:389)
    at com.utils.Utils.deleteDirectory(Utils.java:386)
    at com.utils.Utils.deleteDownloadFolder(Utils.java:375)
    at com.utils.Utils.removeEverythingRelatedToTorrent(Utils.java:87)
    at com.steps.MyStepdefs.applicationCreateActiveTorrentFor(MyStepdefs.java:297)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at cucumber.runtime.Utils$1.call(Utils.java:40)
    at cucumber.runtime.Timeout.timeout(Timeout.java:16)
    at cucumber.runtime.Utils.invoke(Utils.java:34)
    at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:38)
    at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
    at cucumber.runtime.Runtime.runStep(Runtime.java:300)
    at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
    at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
    at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
    at cucumber.runtime.model.CucumberScenarioOutline.run(CucumberScenarioOutline.java:46)
    at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
    at cucumber.runtime.Runtime.run(Runtime.java:122)
    at cucumber.api.cli.Main.run(Main.java:36)
    at cucumber.api.cli.Main.main(Main.java:18)


Min deleteDirectory metode fjerner først alle filerne inde i hver mappe, den forsøger at slette, og først vil den fjerne mappen. Undtagelsen angiver, at sletningen af ​​hver fil i den pågældende mappe var vellykket, fordi hvis ikke, ville jeg få en undtagelse tidligere, da jeg forsøgte at fjerne en af ​​mappens filer.


Mit spørgsmål er - Hvorfor får jeg den undtagelse?

Bedste reference


Javadok af java.nio.file.Files.delete(Path path) er tydelig:



  Hvis filen er en mappe, skal mappen være tom.



Det fremgår også:



  Denne metode kan bruges med walkFileTree-metoden til at slette en
  mappe og alle poster i mappen eller et helt fil-træ
  hvor det er nødvendigt



Brug af Files.walkFileTree() ville gøre din kode klarere og kortere, men bemærk at det ikke løser dit aktuelle problem.

Udover din rekursive metode til at slette alle ressourcer er det korrekt, når du sletter ressourcer ved at starte med den dybere og ved at bakke op på de mindre dybe.


Problemet er et andet sted: Du opretter faktisk tekstfilerne med Files.newByteChannel(), der skaber nogle SeekableByteChannel forekomster, der er forbundet til File s. Derfor ser det ud til at forhindre, at filerne slettes i flyve, som du påberåber Files.delete(directoryToBeDeleted.toPath());.

Så lukke strømmen før sletning af filerne, og det skal fungere.