我想在 Java 中检查目录是否为空。但是该目录中可能有很多文件,所以如果可能的话,我想在不查询其文件列表的情况下执行此操作。
使用 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();
}
}
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 返回一个延迟填充的 Stream 它将解决与执行时间相关的问题。
java.io.File
source code,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 中实现。
boolean isEmptyDirectory(Path dir) throws IOException {
try (var entries = Files.list(dir)) {
return entries.count() == 0;
}
}
类似于@Minnow 的解决方案(但方法调用较少),此解决方案的好处是“作为 Files.list 返回一个延迟填充的 Stream,它将解决与执行时间相关的问题。”
这是一个肮脏的解决方法,但你可以尝试删除它(使用
delete
方法),如果删除操作失败,则目录不为空,如果成功,则目录为空(但你必须重新创建它,这并不整洁)。我会继续寻找更好的解决方案。
编辑:我从 java.nio.file.Files 类中找到了 walkFileTree: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.对于与这个问题相关的其他问题(在不使用 list() 为大数组分配内存的目录中列出文件),答案总是“你不能,除非你使用 JNI”,这两者都是平台依赖和丑陋。
如果您可以忍受依赖于平台的代码 - 您可以通过加载系统库并使用其 API 来尝试使用实际的本机代码。
例如在 Windows 中,您有一个名为 FindFirstFile()
的
Win32 API以及目录名称(不带 尾部反斜杠)。如果它返回
.
和 ..
以外的内容,您就知道该目录不为空。它不会列出所有文件,所以它比file.list()
快得多。
opendir
。出于您的目的,逻辑是相同的。
当然 - 调用本机方法在可用性和初始库加载方面有代价,它应该在它保存在 FS 查询时被否定。
Path checkIfEmpty=Paths.get("Pathtofile");
DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
Iterator files = ds.iterator();
if(!files.hasNext())
Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));
directory.isDirectory() && directory.list().length > 0 // directory is a File obj
对于如何检查目录是否为空,我也有很长一段时间的困惑 但答案很简单 使用
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])
}
}
}
}
我想添加到开发人员的答案中。检查是否是目录不应该在一个 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;
}