68 votes

Récupération de fichiers d'un répertoire contenant une grande quantité de fichiers

J'ai un répertoire qui contient près de 14 000 000 d'échantillons audio au format * .wav.

Tout le stockage en clair, pas de sous-répertoires.

Je veux parcourir les fichiers en boucle, mais lorsque j'utilise DirectoryInfo.GetFiles() sur ce dossier, l'application entière se fige pendant quelques minutes!

Cela peut-il être fait d'une autre manière? Peut-être lire 1000, les traiter, puis prendre 1000 prochains et ainsi de suite?

Merci d'avance!

95voto

Haris Hasan Points 17497

Avez-vous essayé EnumerateFiles méthode de la classe DirectoryInfo?

Comme Dit MSDN

L' EnumerateFiles et GetFiles méthodes diffèrent comme suit: Lorsque vous utiliser EnumerateFiles, vous pouvez commencer à énumérant la collection de FileInfo objets avant de l'ensemble de la collection est de retour; lorsque vous utiliser GetFiles, vous devez attendre pour l'ensemble de la baie de FileInfo objets être retourné avant de pouvoir accéder à la matrice. Par conséquent, lorsque vous êtes en travaillant avec de nombreux fichiers et répertoires, EnumerateFiles peut être plus efficace.

47voto

Marc Gravell Points 482669

Dans .NET 4.0, Directory.EnumerateFiles(...) est IEnumerable<string> (plutôt que string[] de Directory.GetFiles(...) ), afin de pouvoir diffuser des entrées plutôt que de les mettre en tampon tout; c'est à dire

 foreach(var file in Directory.EnumerateFiles(path)) {
    // ...
}
 

19voto

DXM Points 2519

vous frappez à la limitation de système de fichiers de Windows lui-même. Lorsque le nombre de fichiers dans un répertoire pousse à un grand nombre (et 14M est bien au-delà de ce seuil), accès à l'annuaire devient incroyablement lent. Il n'a pas vraiment d'importance si vous lisez un fichier à un moment ou 1000, c'est juste l'accès de répertoire.

Une façon de résoudre ce problème est de créer des sous-répertoires et de briser vos fichiers en groupes. Si chaque répertoire a 1000 à 5000 (deviner, mais vous pouvez expérimenter avec des nombres réels), alors vous devriez obtenir des performances décentes ouverture/création/suppression de fichiers.

C'est pourquoi si vous regardez des applications comme Doxygen, qui crée un fichier pour chaque classe, ils suivent ce régime et de tout mettre en 2 niveaux de sous-répertoires qui utilisent des noms aléatoires.

8voto

Hasan Khan Points 20723

Utilisez les fonctions Win32 Api FindFile pour le faire sans bloquer l'application.

Vous pouvez également appeler Directory.GetFiles dans un System.Threading.Task (TPL) pour éviter le gel de votre interface utilisateur.

3voto

Faizul Hussain Points 56

J'aborde souvent le problème de l'accès à des fichiers volumineux dans un seul répertoire. Les sous-répertoires sont une bonne option, mais bientôt même, ils n'offrent parfois pas beaucoup d'aide. Ce que je fais maintenant est de créer un fichier index - un fichier texte avec les noms de tous les fichiers du répertoire (à condition que je crée des fichiers dans ce répertoire). J'ai ensuite lu le fichier d'index, puis ouvert le fichier réel du répertoire pour le traitement.

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