webentwicklung-frage-antwort-db.com.de

So prüfen Sie, ob ein Verzeichnis in Java leer ist

Ich möchte prüfen, ob das Verzeichnis in Java leer ist. Es besteht jedoch die Möglichkeit, dass sich in diesem Verzeichnis viele Dateien befinden. Ich möchte dies daher tun, ohne die Dateiliste abzufragen, wenn dies möglich ist.

48
Csq

Mit JDK7 können Sie Files.newDirectoryStream verwenden, um das Verzeichnis zu öffnen, und dann die hasNext () - Methode des Iterators verwenden, um zu testen, ob alle Dateien vor dem Iterator vorhanden sind (vergessen Sie nicht, den Stream zu schließen). Dies sollte für große Verzeichnisse oder für Verzeichnisse, die sich in einem Remote-Dateisystem befinden, im Vergleich zu den Listenmethoden Java.io.File besser funktionieren.

Beispiel:

private static boolean isDirEmpty(final Path directory) throws IOException {
    try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) {
        return !dirStream.iterator().hasNext();
    }
}
67
Alan
File parentDir =  file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
    LOGGER.info("Directory is empty");
} else {
    LOGGER.info("Directory is not empty");
}
16
Developer

Unter Berücksichtigung der Java.io.FileQuellcode , list() macht dies:

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

Es ruft eine native Methode auf, die ein Byte-Array übergibt, um Dateien daraus zu erhalten. Wenn eine Methode null zurückgibt, ist das Verzeichnis leer. 

Was bedeutet, sie haben nicht einmal eine native Methode, um die Verzeichnisleere zu überprüfen, ohne Dateien aufzulisten. Daher gibt es keine Möglichkeit, dass sie eine Implementierung in Java haben, um zu überprüfen, ob das Verzeichnis leer ist.

Outcome: Prüfen, ob das Verzeichnis leer ist, ohne dass Dateien aufgelistet werden, ist noch nicht in Java implementiert.

8
JMelnik

Dies ist eine fehlerhafte Problemumgehung, aber Sie können versuchen, es zu löschen (mit der delete-Methode). Wenn der Löschvorgang fehlschlägt, ist das Verzeichnis nicht leer. Wenn es gelingt, ist es leer (es muss jedoch erneut erstellt werden) es, und das ist nicht ordentlich). Ich suche weiter nach einer besseren Lösung.

EDIT: Ich habe walkFileTree von Java.nio.file.Files Klasse gefunden: http://download.Java.net/jdk7/docs/api/Java/nio/file/Files.html #walkFileTree (Java.nio.file.Path , Java.nio.file.FileVisitor) Das Problem ist, dass dies nur Java 7 ist.

Ich habe S.O gesucht. Für andere Fragen, die sich auf dieses Problem beziehen (Auflisten von Dateien in einem Verzeichnis ohne Verwendung von list (), das Speicherplatz für ein großes Array zuordnet), lautet die Antwort immer "Sie können nicht, es sei denn, Sie verwenden JNI", was beides ist plattformabhängig und hässlich.

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

Wenn Files.list einen faulen Stream zurückgibt, wird das Problem mit der Ausführungszeit behoben.

4
Minnow

Wenn Sie mit plattformabhängigem Code leben können, können Sie den tatsächlichen nativen Code verwenden, indem Sie eine Systembibliothek laden und ihre APIs verwenden.

In Windows haben Sie beispielsweise eine Win32-API namens FindFirstFile() mit dem Verzeichnisnamen (ohne einen nachgestellten Backslash). Wenn etwas anderes als . und .. zurückgegeben wird, wissen Sie, dass das Verzeichnis nicht leer ist. Es werden nicht alle Dateien aufgelistet, es ist also viel schneller als file.list().

Das Äquivalent unter Unix lautet opendir . Für Ihre Zwecke wäre die Logik dieselbe.

Natürlich hat das Aufrufen von systemeigenen Methoden einen Preis für die Benutzerfreundlichkeit und das anfängliche Laden der Bibliothek, das bis zu der Zeit, die es bei den FS - Abfragen gespart wird, negiert werden sollte.

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

Ich möchte zur Antwort des Entwicklers hinzufügen. Überprüfen, ob es sich um ein Verzeichnis handelt oder nicht, sollte sich nicht in einem If-Operator befinden, da in der Logik Fehler vorliegen. Zuerst prüfen Sie das Verzeichnis oder nicht, und erst nachdem Sie das Verzeichnis konsistent geprüft haben, erhalten Sie eine falsche Antwort, wenn das übertragene Methodenverzeichnis nicht vorhanden ist. Überprüfe es einfach. Sollte so sein:

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;
}
0
Eugene Shamkin

Ich hatte auch diese Verwirrung für eine lange Zeit, um zu überprüfen, ob das Verzeichnis leer war oder nicht, aber die Antwort ist ganz einfach zu verwenden

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])
           }
       }
   }
}
0
Radhesh Khanna