Как проверить, является ли каталог пустым в Java - PullRequest
50 голосов
/ 09 мая 2011

Я хотел бы проверить, является ли каталог пустым в Java. Но есть вероятность, что в этом каталоге много файлов, поэтому я бы хотел сделать это, не обращаясь к списку файлов, если это возможно.

Ответы [ 9 ]

73 голосов
/ 09 мая 2011

С JDK7 вы можете использовать Files.newDirectoryStream, чтобы открыть каталог, а затем использовать метод hasNext () итератора, чтобы проверить, есть ли какие-либо файлы для перебора (не забудьте закрыть поток).Это должно работать лучше для огромных каталогов или там, где каталог находится в удаленной файловой системе по сравнению с методами списка java.io.File.

Пример:

private static boolean isDirEmpty(final Path directory) throws IOException {
    try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) {
        return !dirStream.iterator().hasNext();
    }
}
20 голосов
/ 16 апреля 2014
File parentDir =  file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
    LOGGER.info("Directory is empty");
} else {
    LOGGER.info("Directory is not empty");
}
8 голосов
/ 09 мая 2011

С учетом java.io.File исходный код , list() метод делает:

    public java.lang.String[] list() {
    ...
        byte[][] implList = listImpl(bs);
        if (implList == null) {
           // empty list
           return new String[0];
        }     
     ...
     }

     private synchronized static native byte[][] listImpl(byte[] path);

Вызывает собственный метод, передающий байтовый массив для получения файлов из него. Если метод возвращает null, это означает, что каталог пуст.

Что означает , у них даже нет собственного метода проверки пустоты каталогов без перечисления файлов, поэтому у них не было бы никакой реализации в java для проверки, является ли каталог пустым.

Результат : проверка, является ли каталог пустым без списка файлов, пока не реализован в Java.

7 голосов
/ 01 декабря 2016
if(!Files.list(Paths.get(directory)).findAny().isPresent()){
    Files.delete(Paths.get(directory));
 }

As Files.list Возвращает лениво заполненный поток, это решит проблему, связанную со временем выполнения.

4 голосов
/ 09 мая 2011

Это грязный обходной путь, но вы можете попытаться удалить его (с помощью метода delete), и если операция удаления не удалась, каталог не пуст, если он успешен, то он пуст (но вы надо воссоздать его, и это не аккуратно). Я продолжу поиск лучшего решения.

РЕДАКТИРОВАТЬ : Я нашел walkFileTree из класса java.nio.file.Files: http://download.java.net/jdk7/docs/api/java/nio/file/Files.html#walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor) Проблема в том, что это только Java 7.

Я искал С.О. на другие вопросы, связанные с этой самой проблемой (перечисление файлов в каталоге без использования list (), который выделяет память для большого массива), и ответ на этот вопрос довольно часто: «Вы не можете, если вы не используете JNI», который одновременно зависит от платформы и некрасиво.

3 голосов
/ 09 мая 2011

Если вы можете жить с зависимым от платформы кодом - вы можете попробовать использовать реальный собственный код, загрузив системную библиотеку и используя ее API.

Например, в Windows у вас есть Win32 API с именем FindFirstFile() с именем каталога ( без с обратной косой чертой). Если он возвращает что-то отличное от . и .., вы знаете, что каталог не пустой. Он не будет перечислять все файлы, поэтому он намного быстрее, чем file.list().

Эквивалент в Unix: opendir. Для ваших целей логика будет такой же.

Конечно, вызов нативных методов имеет цену на удобство использования и начальную загрузку библиотеки, которая должна быть сведена на нет к тому времени, когда она сэкономит на запросах FS.

2 голосов
/ 06 августа 2012
     Path checkIfEmpty=Paths.get("Pathtofile");
     DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
     Iterator files = ds.iterator();
     if(!files.hasNext())
         Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));
0 голосов
/ 02 ноября 2018

Я хочу добавить в ответ разработчика. Проверка, является ли он каталогом или нет, не должен быть в одном операторе If, потому что у вас будет ошибка в логике. Прежде всего, вы проверяете, является ли это каталогом или нет, и только после этого вы проверяете согласованность каталога, потому что вы получите неправильный ответ, если переданный методу метод не существует. Просто проверь это. Должно быть так:

if (file.isDirectory()) {
    if( file.list().length == 0) {
        logger.info("Directory is empty");
        return false;
    } else {
        logger.info("Directory is not empty");
        return true;
    }
} else {
    return false;
}
0 голосов
/ 30 июня 2017

У меня также была эта путаница в течение долгого времени о том, как проверить, пуст ли каталог или нет, но ответ довольно прост.

class isFileEmpty{
public static void main(String args[]){
File d = new File(//Path of the Directory you want to check or open);
String path = d.getAbsolutePath().toString();
File dir = new File(path);
File[] files = dir.listFiles();
if(!dir.exists()){
System.out.Println("Directory is Empty");
}
else{
for(int i =0;i<files.length;i++){
System.out.Println(files[i])
           }
       }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...