Внутри существующей папки я создал папку и внутри нее несколько файлов, используя этот метод:
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);
}
Структура папок / файлов:
- torrents-test
- folder1
- File-I-Created-1
- File-I-Created-2
- File-I-Created-3
Затем я попытался удалить папку torrents-test таким способом:
void deleteDirectory(File directoryToBeDeleted) throws IOException {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteDirectory(file);
}
}
Files.delete(directoryToBeDeleted.toPath());
}
Затем я получил исключение, которое сообщает мне, что папка folder1 не пуста, поэтому я не могу ее удалить:
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)
Мой метод deleteDirectory сначала удаляет все файлы внутри каждой папки, которую он пытается удалить, и только затем удаляет папку. Исключение означает, что удаление каждого файла внутри этой папки было успешным, потому что в противном случае я бы получил исключение раньше при попытке удалить один из файлов этой папки.
У меня вопрос - Почему я получаю это исключение?
@Andreas Это было или DeleteAllFilesAndFoldersInsideFolder. Я выбрал более короткий. Но я открыт для предложений.
Почему вы смешиваете старые и новые API? File против Path. Вместо рекурсивного вызова с File.listFiles() используйте Files.walkFileTree(...).
delete(File fileOrDir). Или еще лучше, используйте более новый NIO.2, например delete(Path fileOrDir).
@Andreas, использующий его вне класса, сделает неясным какие, который я пытаюсь удалить.
Действительно? Параметр - File (или Path), поэтому метод под названием delete() может сбивать с толку, как? Никто бы не подумал, например, удаляет таблицу базы данных.
@Andreas При использовании Files.walkFileTree(...) я все еще получаю то же исключение после, успешно удаляя файлы внутри этой папки.




Документация java.nio.file.Files.delete(Path path) ясна:
If the file is a directory then the directory must be empty.
Также говорится:
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.
Использование Files.walkFileTree() сделает ваш код более понятным и коротким, но учтите, что это не решит вашу настоящую проблему.
Кроме того, ваш рекурсивный метод удаления всех ресурсов верен, поскольку вы удаляете ресурсы, начиная с более глубокого и копируя менее глубокие.
Проблема в другом: действительно, вы создаете текстовые файлы с помощью Files.newByteChannel(), который создает несколько экземпляров SeekableByteChannel, подключенных к File. Следовательно, похоже, что это предотвращает удаление файлов на лету при вызове Files.delete(directoryToBeDeleted.toPath());.
Поэтому закройте потоки перед удалением файлов, и он должен работать.
Должно быть, раньше у меня были исключения, указывающие на то, что файлы не были удалены .... Но я не.
Если у вас есть это сообщение об ошибке, это означает, что файлы эффективно не были удалены одновременно с вызовом метода. На самом деле причина проблемы более тонкая. Я обновился.
deleteDirectoryс именем файла? Вы делаете это в рекурсивных вызовах.