Stav Alfi
Stav Alfi

Reputation: 13923

Can't remove empty folder

Inside an existing folder, I created a folder and inside it multiple files using this method:

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);
}

The folders/files structure is:

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

Then I tried to delete the folder torrents-test using this method:

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

Then I got an exception which tells me that the folder folder1 is not empty so I can't delete it:

java.nio.file.DirectoryNotEmptyException: C:\GIT\university\torrentx\torrents-test\folder1
    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)

My deleteDirectory method first remove all the files inside every folder it tries to delete and only then it will remove the folder. The exception indicates the deletion of every file inside that folder was successful because if not, I would get an exception earlier while trying to remove one of that folder's files.

My question is - Why do I get that exception?

Upvotes: 2

Views: 453

Answers (1)

davidxxx
davidxxx

Reputation: 131346

The javadoc of java.nio.file.Files.delete(Path path) is clear :

If the file is a directory then the directory must be empty.

It is also stated :

This method can be used with the walkFileTree method to delete a directory and all entries in the directory, or an entire file-tree where required.

Using Files.walkFileTree() would make your code clearer and shorter but note that it will not solve your actual problem.
Besides your recursive method to delete all resources is correct as you delete resources by starting by the deeper and by go backing up the less deep.

The problem is somewhere else: indeed you are creating the text files with Files.newByteChannel() that creates some SeekableByteChannel instances that are connected to the Files. Consequently it seems to prevent the files from being deleted on the fly as you invoke Files.delete(directoryToBeDeleted.toPath());.
So close the streams before deleting the files and it should work.

Upvotes: 3

Related Questions