1. Обзор
В этом кратком руководстве мы познакомимся с несколькими способами узнать, является ли каталог пустым или нет.
2. Использование Files.newDirectoryStream
Начиная с Java 7, метод Files.newDirectoryStream
возвращает DirectoryStream <Path>
для перебора всех записей в каталоге . Таким образом, мы можем использовать этот API, чтобы проверить, является ли данный каталог пустым или нет:
public boolean isEmpty(Path path) throws IOException {
if (Files.isDirectory(path)) {
try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
return !directory.iterator().hasNext();
}
}
return false;
}
Для входных данных, не относящихся к каталогу, мы вернем false
, даже не пытаясь загрузить записи каталога:
Path aFile = Paths.get(getClass().getResource("/notDir.txt").toURI());
assertThat(isEmpty(aFile)).isFalse();
С другой стороны, если ввод является каталогом, мы попытаемся открыть DirectoryStream
для этого каталога. Тогда мы будем считать каталог пустым тогда и только тогда, когда первый вызов метода hasNext()
возвращает false
. В противном случае он не пуст:
Path currentDir = new File("").toPath().toAbsolutePath();
assertThat(isEmpty(currentDir)).isFalse();
DirectoryStream
— это Closeable ресурс, поэтому мы заключаем его в блок try
-with-resources . Как и следовало ожидать, метод isEmpty
возвращает true
для пустых каталогов:
Path path = Files.createTempDirectory("foreach-empty");
assertThat(isEmpty(path)).isTrue();
Здесь мы используем Files.createTempDirectory
для создания пустого и временного каталога.
3. Использование Files.list
Начиная с JDK 8, метод Files.list
использует для внутреннего использования Files.newDirectoryStream
API для предоставления Stream<Path>
. Каждый путь
является записью внутри данного родительского каталога. Поэтому мы также можем использовать этот API для той же цели:
public boolean isEmpty(Path path) throws IOException {
if (Files.isDirectory(path)) {
try (Stream<Path> entries = Files.list(path)) {
return !entries.findFirst().isPresent();
}
}
return false;
}
Опять же, мы касаемся только первой записи, используя метод findFirst
. Если возвращаемый необязательный
параметр пуст, то и каталог пуст.
Stream
поддерживается ресурсом ввода-вывода , поэтому мы обязательно выпускаем его надлежащим образом, используя блок try-with-resources.
4. Неэффективные решения
И Files.list
, и Files.newDirectoryStream
будут лениво перебирать записи каталога. Поэтому они будут очень эффективно работать с огромными каталогами . Однако такие решения не будут работать в этом сценарии:
public boolean isEmpty(Path path) {
return path.toFile().listFiles().length == 0;
}
Это с готовностью загрузит все записи внутри каталога, что будет довольно неэффективно при работе с огромными каталогами.
5. Вывод
В этом коротком руководстве мы познакомились с несколькими эффективными способами проверки того, пуст каталог или нет.
Как обычно, все примеры доступны на GitHub .