74 votes

Compter le nombre de fichiers dans un répertoire en utilisant Java

Comment compter le nombre de fichiers dans un répertoire en utilisant Java ? Pour simplifier, supposons que le répertoire n'a pas de sous-répertoires.

Je connais la méthode standard de :

new File(<directory path>).listFiles().length

Mais cela va effectivement passer par tous les fichiers du répertoire, ce qui peut prendre du temps si le nombre de fichiers est important. De plus, je ne me soucie pas des fichiers actuels du répertoire, sauf si leur nombre est supérieur à un nombre fixe élevé (disons 5000).

Je devine, mais le répertoire (ou son i-node dans le cas d'Unix) ne stocke-t-il pas le nombre de fichiers qu'il contient ? Si je pouvais obtenir ce nombre directement à partir du système de fichiers, ce serait beaucoup plus rapide. Je dois effectuer cette vérification pour chaque requête HTTP sur un serveur Tomcat avant que le back-end ne commence à effectuer le véritable traitement. La vitesse est donc d'une importance capitale.

Je pourrais lancer un démon de temps en temps pour vider le répertoire. Je le sais, alors ne me donnez pas cette solution.

0 votes

Si le répertoire contient potentiellement un grand nombre de fichiers (plus de 1000), vous pouvez éviter d'allouer le tableau retourné par les méthodes de liste de fichiers. Je n'ai pas encore essayé, mais vous pourriez peut-être utiliser listFiles et lui passer une instance de FileFilter qui fait le comptage des fichiers dans la méthode accept, tout en retournant false pour tous les fichiers. Je suppose que cela évite l'allocation d'un tableau, tout en vous donnant un compte de fichiers.

0 votes

Ignorez mon dernier commentaire... Selon l'implémentation du JDK, le tableau peut être alloué de toute façon (sous le capot). Cela semble être le cas dans openjdk en tout cas.

0 votes

Pour Java 7 et les versions ultérieures, ce problème a une bonne solution avec une API Java standard. Voir la réponse de @mateuscb ci-dessous - stackoverflow.com/questions/687444/ .

92voto

Varkhan Points 6756

Ah... la raison pour laquelle il n'y a pas de méthode directe en Java pour faire cela est l'abstraction du stockage de fichiers : certains systèmes de fichiers peuvent ne pas avoir le nombre de fichiers dans un répertoire facilement disponible... ce nombre peut même ne pas avoir de signification du tout (voir par exemple les systèmes de fichiers distribués, P2P, les fs qui stockent les listes de fichiers comme une liste liée, ou les systèmes de fichiers soutenus par une base de données...). Donc oui,

new File(<directory path>).list().length

est probablement votre meilleure option.

1 votes

IMO, cela ne justifie pas de ne pas avoir une telle méthode - elle pourrait simplement retourner null pour FS où N/A. Les FS exotiques ne sont pas une raison de gaspiller des cycles pour obtenir un tableau.

0 votes

Ça n'a pas de sens pour moi. Pourquoi pouvez-vous obtenir tous les fichiers et les compter mais pas simplement obtenir le nombre ? Où est la différence ?

1 votes

Attention File.list() peut retourner null par exemple lorsque le fichier n'est pas un répertoire.

17voto

Michael Myers Points 82361

Malheureusement, je pense que c'est déjà le meilleur moyen (bien que [list()](http://java.sun.com/javase/6/docs/api/java/io/File.html#list()) est légèrement meilleur que listFiles() puisqu'il ne construit pas File objets).

13voto

Marty Lamb Points 1330

Cela peut ne pas être approprié pour votre application, mais vous pouvez toujours essayer un appel natif (en utilisant jni ou jna ), ou exécuter une commande spécifique à la plate-forme et lire la sortie avant de revenir à list().length. Sur *nix, vous pouvez exécuter ls -1a | wc -l (note - c'est dash-one-a pour la première commande, et dash-lowercase-L pour la seconde). Je ne suis pas sûr de ce qui serait correct sous Windows - peut-être juste un dir et cherchez le résumé.

Avant de vous lancer dans une telle entreprise, je vous recommande vivement de créer un répertoire contenant un très grand nombre de fichiers et de voir si list().length prend vraiment trop de temps. Comme ce blogueur suggère, vous pourriez ne pas vouloir transpirer cela.

Je choisirais probablement la réponse de Varkhan moi-même.

1 votes

Est -a approprié dans le cas de la ls solution ? Ne serait-ce pas aussi une liste . y .. ?

0 votes

Et je pense que vous pourriez vouloir un -f s'il y a beaucoup de fichiers dans le répertoire, sinon la plupart du temps sera passé à faire le tri par défaut.

4voto

Renaud Points 3226

Si vous avez des répertoires contenant de très nombreux fichiers (>100'000), voici une méthode (non portable) :

String directoryPath = "a path";

// -f flag is important, because this way ls does not sort it output,
// which is way faster
String[] params = { "/bin/sh", "-c",
    "ls -f " + directoryPath + " | wc -l" };
Process process = Runtime.getRuntime().exec(params);
BufferedReader reader = new BufferedReader(new InputStreamReader(
    process.getInputStream()));
String fileCount = reader.readLine().trim() - 2; // accounting for .. and .
reader.close();
System.out.println(fileCount);

1voto

Sebastian Celis Points 7284

Malheureusement, comme l'a dit mmyers, File.list() est à peu près le plus rapide que vous puissiez obtenir en utilisant Java. Si la vitesse est aussi importante que vous le dites, vous pouvez envisager d'effectuer cette opération particulière en utilisant JNI . Vous pouvez alors adapter votre code à votre situation particulière et à votre système de fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X