Csq
Csq

Reputation: 5855

How to check if a directory is empty in Java

I'd like to check if directory is empty in Java. But there is a possibility that there are many files in that directory so I'd like to do it without querying its file list, if possible.

Upvotes: 78

Views: 80820

Answers (11)

Leo Ka
Leo Ka

Reputation: 11

You can check whether directory isDirectory() after all (and not a file) and then, call list() to get its content and finally, get the length value to see whether there is content, i.e., whether it's not empty.

directory.isDirectory() && directory.list().length > 0 // directory is a File obj

Upvotes: 0

Peng
Peng

Reputation: 1491

boolean isEmptyDirectory(Path dir) throws IOException {
    try (var entries = Files.list(dir)) {
        return entries.count() == 0;
    }
}

Similar to @Minnow's solution (but with less method calls), this solution has the benefit "As Files.list Return a lazily populated Stream it will solve your execution time related issue."

Upvotes: 6

Eugene Shamkin
Eugene Shamkin

Reputation: 183

I want to add to answer of Developer. Checking is it directory or not should not be in one If operator, because you will have mistake in logic. First of all you checking is it directory or not, and only after that you checking directory consistensy, becouse you will get wrong answer if the tranfered to method directory is not exist. Just check it. Should be like this:

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;
}

Upvotes: -1

Radhesh Khanna
Radhesh Khanna

Reputation: 137

I also had this Confusion for a Long time about how to check if the Directory was empty or not But the Answer is Quite Simple use

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])
           }
       }
   }
}

Upvotes: -1

Minnow
Minnow

Reputation: 515

if(!Files.list(Paths.get(directory)).findAny().isPresent()){
    Files.delete(Paths.get(directory));
 }

As Files.list Return a lazily populated Stream it will solve your execution time related issue.

Upvotes: 21

d1e
d1e

Reputation: 6452

Considering from java.io.File source code, list() method does:

    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);

It calls a native method passing a byte array to get files from it. If a method returns null it means directory is empty.

Which means, they don't even have a native method, to check for directory emptiness without listing files, so there is no way they would have an implementation in java for checking if directory is empty.

Outcome: checking if directory is empty without listing files is not implemented in java, yet.

Upvotes: 8

Divanshu
Divanshu

Reputation: 1907

File parentDir =  file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
    LOGGER.info("Directory is empty");
} else {
    LOGGER.info("Directory is not empty");
}

Upvotes: 29

Alan
Alan

Reputation: 2877

With JDK7 you can use Files.newDirectoryStream to open the directory and then use the iterator's hasNext() method to test there are any files to iterator over (don't forgot to close the stream). This should work better for huge directories or where the directory is on a remote file system when compared to the java.io.File list methods.

Example:

private static boolean isDirEmpty(final Path directory) throws IOException {
    try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) {
        return !dirStream.iterator().hasNext();
    }
}

Upvotes: 110

lesolorzanov
lesolorzanov

Reputation: 3606

     Path checkIfEmpty=Paths.get("Pathtofile");
     DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
     Iterator files = ds.iterator();
     if(!files.hasNext())
         Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));

Upvotes: 2

gd1
gd1

Reputation: 11403

This is a dirty workaround, but you can try do delete it (with the delete method), and if the delete operation fails, then the directory is not empty, if it succeeds, then it is empty (but you have to re-create it, and that's not neat). I'll continue searching for a better solution.

EDIT: I've found walkFileTree from 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) Problem is that this is Java 7 only.

I've searched S.O. for other questions related to this very issue (listing files in a directory w/o using list() which allocates memory for a big array) and the answer is quite always "you can't, unless you use JNI", which is both platform dependent and ugly.

Upvotes: 4

RonK
RonK

Reputation: 9652

If you can live with platform dependent code - you can try using actual native code by loading a system library and using its APIs.

In Windows for example you have a Win32 API named FindFirstFile() with the directory name (without a trailing backslash). If it returns something other than . and .. you know the directory isn't empty. It will not list all the files so it's much faster than file.list().

The equivalent on Unix is opendir. For your purposes the logic would be the same.

Of course - calling native methods has a price on usability and the initial library loading which should be negated by the time it will save on the FS queries.

Upvotes: 3

Related Questions