Есть ли способ рекурсивного удаления целых каталогов в Java?
В обычном случае можно удалить пустой каталог. Однако, когда дело доходит до удаления целых каталогов с содержимым, это уже не так просто.
Как вы удаляете целые каталоги с содержимым в Java?
java
file-io
filesystems
delete-directory
paweloque
источник
источник
Ответы:
Вы должны проверить Apache Commons-IO . Он имеет класс FileUtils, который будет делать то, что вы хотите.
источник
С Java 7 мы можем наконец сделать это с надежным обнаружением символической ссылки. (Я не считаю, что Apache commons-io в настоящее время имеет надежное обнаружение символических ссылок, поскольку он не обрабатывает ссылки в Windows, созданные с помощью
mklink
.)Ради истории, вот ответ до Java 7, который следует за символическими ссылками.
источник
foo
с такой ссылкойfoo/link
, что приlink->/
вызовеdelete(new File(foo))
будет удалено столько файловой системы, сколько разрешено вашему пользователю !!В Java 7+ вы можете использовать
Files
класс. Код очень прост:источник
super.postVisitDirectory(dir, exc);
вашpostVisitDirectory
метод, чтобы взорвать, если прогулка не может перечислить каталог.Однострочное решение (Java8) для рекурсивного удаления всех файлов и каталогов, включая начальный каталог:
Мы используем компаратор для обратного порядка, иначе File :: delete не сможет удалить, возможно, непустую директорию. Итак, если вы хотите сохранить каталоги и удалять только файлы, просто удалите компаратор в sorted () или полностью удалите сортировку и добавьте фильтр файлов:
источник
.sorted(Comparator.reverseOrder())
ПредложениеComparator::reverseOrder
действительно не работает. См: stackoverflow.com/questions/43036611/....sorted((f1, f2) -> f2.compareTo(f1))
в сравненииf2
сf1
вместоf1
сf2
.В Java 7 добавлена поддержка прогулочных каталогов с обработкой символических ссылок:
Я использую это как откат от платформо-зависимых методов (в этом непроверенном коде):
(SystemUtils из Apache Commons Lang . Процессы являются частными, но их поведение должно быть очевидным.)
источник
Просто увидел, что мое решение более или менее совпадает с решением Эриксона, просто упаковано как статический метод. Оставьте это где-нибудь, это намного легче, чем устанавливать все Apache Commons для чего-то, что (как вы можете видеть) довольно просто.
источник
Решение со стеком и без рекурсивных методов:
источник
list*
методами для классаjava.io.File
. Из Javadocs: «Возвращает ноль, если это абстрактное имя пути не обозначает каталог или если произошла ошибка ввода-вывода». Итак:if (currList.length > 0) {
становитсяif (null != currList && currList.length > 0) {
Если у вас есть Spring, вы можете использовать FileSystemUtils.deleteRecursively :
источник
Гуавы не было
Files.deleteRecursively(File)
поддерживается до гуавы 9 .Из гуавы 10 :
Поэтому в Guava 11 такого метода нет .
источник
Или, если вы хотите обработать
IOException
:источник
Files.walk(path).iterator().toSeq.reverse.foreach(Files.delete)
walk
метод уже гарантирует прохождение в глубину.Collections.reverseOrder()
поэтому ваш код будетfor (Path p : Files.walk(directoryToDelete).sorted(reverseOrder()).toArray(Path[]::new))
предполагать, что он был статически импортирован.Comparator.reverseOrder
?Files.walk(dir) .sorted(Comparator.reverseOrder()) .toArray(Path[]::new))
источник
источник
f.delete()
подdeleteDirectory(f)
будет выбрасывать NoSuchFileException, потому чтоdeleteDirectory(f)
уже удалить этот файл. Каждый каталог становится путем, когда передаетсяdeleteDirectory(f)
и удаляетсяpath.delete()
. Поэтому нам не нужноf.delete()
вif f.isDerectory
разделе. Итак, просто удалитеf.delete();
в deleteDirectory (f), и это будет работать.Два способа потерпеть неудачу с символическими ссылками и приведенным выше кодом ... и не знаете решения.
Способ № 1
Запустите это, чтобы создать тест:
Здесь вы видите свой тестовый файл и тестовый каталог:
Затем запустите ваш commons-io deleteDirectory (). Вылетает, говоря, что файл не найден. Не уверен, что другие примеры делают здесь. Команда Linux rm просто удалит ссылку, а rm -r в каталоге также.
Способ № 2
Запустите это, чтобы создать тест:
Здесь вы видите свой тестовый файл и тестовый каталог:
Затем запустите ваш commons-io deleteDirectory () или пример кода, который разместили люди. Он удаляет не только каталог, но и ваш тестовый файл, который находится за пределами удаляемого каталога. (Он неявно разыменовывает каталог и удаляет содержимое). rm -r удалит только ссылку. Вам нужно использовать что-то вроде этого, чтобы удалить разыменованные файлы: "find -L dirtodelete -type f -exec rm {} \;".
источник
Вы можете использовать:
org.apache.commons.io.FileUtils.deleteQuietly(destFile);
Удаляет файл, никогда не создавая исключение. Если файл является каталогом, удалите его и все подкаталоги. Разница между File.delete () и этим методом: каталог, который нужно удалить, не обязательно должен быть пустым. Нет исключений, когда файл или каталог не может быть удален.
источник
Оптимальное решение, которое обрабатывает исключение в соответствии с подходом, согласно которому исключение, создаваемое методом, должно всегда описывать то, что этот метод пытался (и не смог) сделать:
источник
В старых проектах мне нужно создавать нативный код Java. Я создаю этот код, похожий на код Paulitex. Видеть, что:
И юнит тест:
источник
Код ниже рекурсивно удаляет все содержимое в данной папке.
источник
Вот основной метод голых костей, который принимает аргумент командной строки, вам может потребоваться добавить собственную проверку ошибок или настроить ее так, как вы считаете нужным.
Надеюсь, это поможет!
источник
Возможно, решением этой проблемы может быть переопределение метода delete класса File с использованием кода из ответа Эриксона:
источник
Без общего ввода-вывода и <Java SE 7
источник
Хотя файлы можно легко удалить с помощью file.delete (), для удаления необходимо, чтобы каталоги были пустыми. Используйте рекурсию, чтобы сделать это легко. Например:
источник
я кодировал эту процедуру, которая имеет 3 критерия безопасности для более безопасного использования.
источник
Что ж, давайте возьмем пример,
Для получения дополнительной информации обратитесь к ресурсам ниже
Удалить каталог
источник
rm -rf
был намного более производительным, чемFileUtils.deleteDirectory
.После обширного бенчмаркинга мы обнаружили, что использование
rm -rf
было в несколько раз быстрее, чем использованиеFileUtils.deleteDirectory
.Конечно, если у вас небольшой или простой каталог, это не имеет значения, но в нашем случае у нас было несколько гигабайт и вложенных вложенных подкаталогов, где это заняло бы более 10 минут
FileUtils.deleteDirectory
и только 1 минуту сrm -rf
.Вот наша грубая реализация Java для этого:
Стоит попробовать, если вы имеете дело с большими или сложными каталогами.
источник
Гуава предоставляет однострочник
MoreFiles.deleteRecursively()
.В отличие от многих общих примеров, он учитывает символические ссылки и не будет (по умолчанию) удалять файлы за пределами указанного пути.
источник