2011-05-08 98 views
40

我想检查Java中的目录是否为空。但是,有可能该目录中有很多文件,所以如果可能的话,我想不做查询它的文件列表。如何检查Java中的目录是否为空

+0

列表()可以在许多文件很慢很长一段时间。 – 2011-05-08 20:28:08

+3

那里可以有多少个文件?你是否遇到过性能问题? – RonK 2011-05-08 20:38:19

+1

当扫描空目录时,我发现.list()占用了超过50%的执行时间。因此,如果您实际上不需要文件列表,找到替代方法可以显着加快速度。 – cottonBallPaws 2014-07-31 18:20:07

回答

54

使用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(); 
    } 
} 
+0

如果在检查之后想要迭代dirStream,会怎么样?我想: 为(路径神器:dirStream){ 但有已经获得了一个迭代器 - 异常 – garyee 2018-01-19 13:44:13

4

这是一个肮脏的解决方法,但您可以尝试删除它(使用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只。

我已经查过S.O.对于与这个问题有关的其他问题(将列表中的文件列在无法使用list()的目录中,该目录为大数组分配内存)并且答案总是“除非使用JNI,否则不能使用JNI”平台依赖和丑陋。

+0

很多答案+1。 – asgs 2011-05-08 20:28:07

+14

目录删除可能由于其他原因而失败 - 例如文件权限。 – 2011-05-08 20:31:11

+1

其实它很丑。希望有一个100%的Java解决方案来做到这一点。仍在搜索中。 – gd1 2011-05-08 20:46:09

3

如果您可以使用平台相关的代码 - 您可以尝试使用实际的本机代码,方法是加载系统库并使用其API。

在Windows中,比如你有一个名为Win32 APIFindFirstFile()目录名(没有斜杠)。如果它返回的信息不是...,那么您知道该目录不是空的。它不会列出所有文件,因此它比file.list()快得多。

Unix上的等价物是opendir。为了你的目的,逻辑将是相同的。

当然 - 调用native方法的可用性和初始库加载的价格应该在FS查询时节省时间。

+1

考虑到绝对没有什么能阻止人们创建不包含“。”的文件。并没有阻止人们创建包含“。”的目录。 - 该解决方案不会有任何好处。虽然我确信有一个或多或少有效的方式来使用本地API来做到这一点,但调用它的开销可能会更糟。根据FS实现这是可以想象的是,OS将不得不枚举所有文件开始与反正 – Voo 2011-05-08 20:43:20

+0

@Voo(不知道NTFS是如何实现的?):正确的用法是忽略'.'和'..'条目。如果一个文件系统不允许你在没有枚举所有文件的情况下获得第一个目录项,那么就没有办法快速检查它是否为空,但是我怀疑这样的文件系统是否会存在。 – Gabe 2011-05-08 21:16:31

+0

@加贝是啊不知道如何详细实施NTFS。修改过的解决方案应该是OP想要什么,除了一个事实,即它是原生的 - 我会承担目录有相当大,以抵消本地通话费用(但你提到已经和问题是关于无论如何,这也没关系)。虽然你应该已经创建了一个新的职位(编辑过的一个人没有很多共同点与原;)),我很乐意给予好评您的文章(或你明白,因为你编辑的贷款的一部分? ) – Voo 2011-05-08 21:24:11

8

java.io.Filesource 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中实现。

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

只是要小心关闭DirectoryStream当您完成(或使用try-与资源),否则你最终得到一个文件句柄泄漏。 – user194715 2013-03-09 18:10:36

11
File parentDir = file.getParentFile(); 
if(parentDir.isDirectory() && parentDir.list().length == 0) { 
    LOGGER.info("Directory is empty"); 
} else { 
    LOGGER.info("Directory is not empty"); 
} 
3
if(!Files.list(Paths.get(directory)).findAny().isPresent()){ 
    Files.delete(Paths.get(directory)); 
} 

由于Files.list返回懒洋洋地填充流将解决您的执行时间有关的问题。

-1

我也有过这样的困惑,有关如何检查目录是空的或不 但答案很简单 使用

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