Я хочу проверить, пуст ли каталог на Java. Но есть вероятность, что в этом каталоге есть много файлов, поэтому я хотел бы сделать это без запроса его списка файлов, если это возможно.
Как проверить, пуст ли каталог в Java
Ответ 1
С помощью JDK7 вы можете использовать Files.newDirectoryStream, чтобы открыть каталог, а затем использовать метод iterator hasNext() для проверки наличия каких-либо файлов на итераторе (не забудьте закрыть поток). Это должно работать лучше для огромных каталогов или где каталог находится в удаленной файловой системе по сравнению с методами списка java.io.File.
Пример:
private static boolean isDirEmpty(final Path directory) throws IOException {
try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) {
return !dirStream.iterator().hasNext();
}
}
Ответ 2
Учитывая 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.
Ответ 3
File parentDir = file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
LOGGER.info("Directory is empty");
} else {
LOGGER.info("Directory is not empty");
}
Ответ 4
Это грязное обходное решение, но вы можете попробовать удалить его (с помощью метода delete
), и если операция удаления не удалась, то каталог не пуст, если он преуспеет, тогда он пуст (но вы должны воссоздать его, а это не аккуратно). Я продолжу поиск лучшего решения.
EDIT: я нашел walkFileTree из java.nio.file.Files class: http://download.java.net/jdk7/docs/api/java/nio/file/Files.html#walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor) Проблема в том, что это только Java 7.
Я искал S.O. для других вопросов, связанных с этой самой проблемой (перечисление файлов в каталоге без использования списка(), который выделяет память для большого массива), и ответ вполне всегда "вы не можете, если вы не используете JNI", который является одновременно зависимой от платформы и уродливой.
Ответ 5
Если вы можете жить с зависимым от платформы кодом - вы можете попробовать использовать собственный собственный код, загрузив системную библиотеку и используя ее API.
В Windows, например, у вас есть Win32 API с именем FindFirstFile()
с именем каталога (без обратной обратной косой черты). Если он возвращает что-то отличное от .
и ..
, вы знаете, что каталог не пуст. Он не будет перечислять все файлы, поэтому он будет намного быстрее, чем file.list()
.
Эквивалент в Unix opendir
. Для ваших целей логика будет одинаковой.
Конечно, вызов собственных методов имеет цену на удобство использования и загрузку исходной библиотеки, которая должна быть сведена к тому времени, когда она будет сохранять запросы FS.
Ответ 6
if(!Files.list(Paths.get(directory)).findAny().isPresent()){
Files.delete(Paths.get(directory));
}
Как Files.list Верните лениво заполненный поток, он решит проблему, связанную с временем выполнения.
Ответ 7
Path checkIfEmpty=Paths.get("Pathtofile");
DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
Iterator files = ds.iterator();
if(!files.hasNext())
Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));
Ответ 8
У меня также было это Confusion в течение долгого времени о том, как проверить, был ли каталог пустым или нет Но ответ довольно простой используйте
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])
}
}
}
}