How to check if a directory is empty in Java
I'd like to check if directory is empty i开发者_C百科n 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.
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();
}
}
File parentDir = file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
LOGGER.info("Directory is empty");
} else {
LOGGER.info("Directory is not empty");
}
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.
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.
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."
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.
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.
Path checkIfEmpty=Paths.get("Pathtofile");
DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
Iterator files = ds.iterator();
if(!files.hasNext())
Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));
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])
}
}
}
}
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;
}
精彩评论