web-dev-qa-db-fra.com

Comment vérifier si un répertoire est vide en Java

J'aimerais vérifier si le répertoire est vide en Java. Mais il y a une possibilité qu'il y ait beaucoup de fichiers dans ce répertoire, j'aimerais donc le faire sans interroger sa liste de fichiers, si possible.

48
Csq

Avec JDK7, vous pouvez utiliser Files.newDirectoryStream pour ouvrir le répertoire, puis utiliser la méthode hasNext () de l'itérateur pour tester la présence de fichiers sur lesquels l'itérateur est placé (n'oubliez pas de fermer le flux). Cela devrait fonctionner mieux pour des répertoires volumineux ou lorsque le répertoire se trouve sur un système de fichiers distant par rapport aux méthodes de liste Java.io.File.

Exemple:

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

Considérant depuis Java.io.Filecode source , list() la méthode ne:

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

Il appelle une méthode native en passant un tableau d'octets pour en extraire des fichiers. Si une méthode retourne null, cela signifie que le répertoire est vide. 

Ce qui signifie, ils n'ont même pas de méthode native pour vérifier le vide du répertoire sans lister les fichiers, il n'y a donc aucun moyen d'implémenter Java pour vérifier si le répertoire est vide.

Résultat: vérifier si le répertoire est vide sans lister les fichiers n'est pas encore implémenté en Java.

8
JMelnik

Cette solution de contournement est sale, mais vous pouvez essayer de la supprimer (avec la méthode delete), et si l'opération de suppression échoue, le répertoire n'est pas vide, s'il réussit, il est vide (mais vous devez recréer et ce n’est pas chouette). Je vais continuer à chercher une meilleure solution.

EDIT: j'ai trouvé walkFileTree à partir de la classe 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) Le problème est qu’il s’agit uniquement de Java 7.

J'ai cherché S.O. pour d'autres questions liées à cette question même (lister des fichiers dans un répertoire sans utiliser list () qui alloue de la mémoire pour un grand tableau) et la réponse est toujours "vous ne pouvez pas, sauf si vous utilisez JNI", qui est à la fois plate-forme dépendante et laide.

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

En tant que Files.list, renvoyez un flux paresseusement peuplé qui résoudra votre problème lié au temps d'exécution.

4
Minnow

Si vous pouvez vivre avec du code dépendant de la plate-forme, vous pouvez essayer d'utiliser du code natif réel en chargeant une bibliothèque système et en utilisant ses API.

Dans Windows, par exemple, vous avez un API Win32 nommé FindFirstFile() avec le nom du répertoire (sans une barre oblique inversée). S'il renvoie autre chose que . et .., vous savez que le répertoire n'est pas vide. Il ne listera pas tous les fichiers, il est donc beaucoup plus rapide que file.list().

L'équivalent sous Unix est opendir . Pour vos besoins, la logique serait la même.

Bien entendu, l'appel de méthodes natives a un prix sur la convivialité et le chargement initial de la bibliothèque, ce qui devrait être annulé au moment où il économisera sur les requêtes FS.

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

Je veux ajouter à la réponse de développeur. Vérifier si c'est un répertoire ou non ne devrait pas être dans un opérateur If, car vous aurez une erreur de logique. Tout d’abord, vous vérifiez s’il s’agit ou non du répertoire, et c’est seulement après avoir vérifié la cohérence du répertoire, car vous obtiendrez une mauvaise réponse si le répertoire de la méthode transféré n’existe pas. Il suffit de vérifier. Devrait être comme ça:

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

J'ai aussi eu cette confusion pendant longtemps sur la façon de vérifier si le répertoire était vide ou non, mais la réponse est une utilisation assez simple

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