node.js fs.readdir récursive recherche dans l'annuaire
Toutes les idées sur un async recherche dans l'annuaire à l'aide de fs.readdir? Je me rends compte que nous avons pu introduire la récursivité et d'appeler le lire en fonction répertoire avec le répertoire suivant pour lire, mais je suis un peu inquiet de ne pas être asynchrone...
Des idées? J'ai regardé nœud-pied qui est très bien, mais ne me donne pas seulement les fichiers dans un tableau, comme readdir n'. Bien que
À la recherche pour la sortie comme...
['file1.txt', 'file2.txt', 'dir/file3.txt']
Vous devez vous connecter pour publier un commentaire.
Il y a essentiellement deux façons d'y parvenir. Dans un environnement asynchrone, vous remarquerez qu'il y a deux types de boucles: série et parallèle. Une série de boucle attend pour une itération à terminer avant de passer à l'itération suivante - ce qui garantit que chaque itération de la boucle est terminée dans l'ordre. Dans une boucle parallèle, toutes les itérations sont lancés dans le même temps, et on peut se terminer avant qu'une autre, cependant, il est beaucoup plus rapide qu'une boucle série. Donc, dans ce cas, il est probablement préférable d'utiliser une boucle parallèle parce qu'il n'a pas d'importance ce que commande la marche terminée, juste aussi longtemps que il remplit et retourne les résultats (sauf si vous les voulez dans l'ordre).
Une boucle parallèle devrait ressembler à ceci:
Une boucle série devrait ressembler à ceci:
Et de le tester sur votre répertoire home (AVERTISSEMENT: la liste des résultats sera énorme si vous avez beaucoup de choses dans votre répertoire home):
EDIT: Amélioration des exemples.
results
tableau?results
tableaufile = dir + '/' + file;
Ce n'est pas recommandé. Vous devez utiliser:var path = require('path'); file = path.resolve(dir, file);
path.resolve(...)
, vous obtiendrez un bon chemin si vous êtes sur Windows ou Unix 🙂 ce qui Signifie que vous obtiendrez quelque chose commeC:\\some\\foo\\path
sur Windows et/some/foo/path
sur les systèmes Unixcode
var trouver = function(dir, nom de fichier, done) { ... var path = require('chemin'); fichier = chemin d'accès.résoudre(dir, fichier); ... trouver(fichier, nom de fichier, function(err, res) { .... } else { if (fichier.indexOf(nom de fichier)>1) { // yee haw, trouvé. résultats.push(fichier); done(null,résultats); } ... find("../","git.exe",function(err,résultats) { ...require('node-dir').files(__dirname, function(err, files) { console.log(files); });
!--
syntaxe, une question a été posée à ce sujet!--
syntaxe ici. Est-il une raison particulière pour qu'ilfor
boucle sur la liste des fichiers à instancier en outre répertoire de la traversée. Les autres incrémente une variable de boucle dans la liste de fichiers. Les deux sont la même chose et très parallèle.fs
au lieu defs.promises
? wouldntfs.promises
être encore mieux?Juste au cas où quelqu'un le trouve utile, j'ai également mis en place un synchrone version.
Astuce: Pour utiliser moins de ressources lors du filtrage. Filtre à l'intérieur de cette fonction elle-même. E. g. Remplacer
results.push(file);
avec le code ci-dessous. Ajuster au besoin:lstat
à la place? Ou bien ajouter un ressemble vérifier pour limiter le niveau de récursivité.Celui-ci utilise le montant maximal de nouveau, buzzwordy fonctionnalités disponibles dans le nœud 8, y compris les Promesses, util/promisify, déstructuration, async-attendent, carte+réduire et plus, ce qui rend votre co-travailleurs gratter la tête comme ils essaient de comprendre ce qui se passe.
Nœud 8+
Sans dépendances externes.
D'utilisation
Nœud 10.10+
Mise à jour pour le nœud 10+ avec encore plus de whizbang:
Noter qu'à partir avec nœud 11.15.0 vous pouvez utiliser
files.flat()
au lieu deArray.prototype.concat(...files)
pour aplatir les fichiers de tableau.Nœud 11+
Si vous voulez sauter tout le monde la tête complètement, vous pouvez utiliser la version suivante à l'aide de async itérateurs. En plus d'être vraiment cool, il permet également aux consommateurs de tirer des résultats de l'un-à-un-temps, rendant le mieux adapté pour les très gros répertoires.
Utilisation a changé parce que le type de retour est maintenant un async itérateur au lieu d'une promesse
Dans le cas où quelqu'un est intéressé, je l'ai écrit plus sur async itérateurs ici: https://qwtel.com/posts/software/async-generators-in-the-wild/
subdir
etsubdirs
est trompeur, car ceux-ci peuvent être en fait des fichiers (je suggère quelque chose commeitemInDir
ouitem_in_dir
ou même simplementitem
à la place.), mais cette solution se sent plus propre que l'on a accepté l'un et l'est beaucoup moins de code. Aussi, je ne le trouve pas beaucoup plus compliqué que le code de la accepté de répondre. +1require(fs).promises
et il suffit de déposerutil.promisify
complètement. Personnellement, je alias fs de fs.des promesses.readdir
AKA l'objet d'options commereaddir(dir, {withFileTypes: true})
ce sera le retour de tous les éléments avec leurs informations de type, de SORTE que nous n'aurons pas besoin d'appelerstat
à tout pour obtenir les informations quereaddir
nous offre maintenant de retour. Cela nous évite d'avoir à faire d'autres sys appels. Détails iciwithFileTypes
. Merci pour l'astuce.A. Ont un look à la module de fichier. Il a une fonction appelée à pied:
Cela peut être pour vous! Et oui, il est asynchrone. Cependant, je crois que vous avez pour agréger le chemin d'accès complet de vous-même, si vous avez besoin d'eux.
B. Une alternative, et même l'un de mes favoris: utilisation de l'unix
find
pour que. Pourquoi faire quelque chose de nouveau, qui a déjà été programmé? Peut-être pas exactement ce que vous avez besoin, mais encore la peine de vérifier:Trouver a un beau construire-dans le mécanisme de mise en cache qui fait des recherches ultérieures très rapide, aussi longtemps que seulement quelques dossier ont changé.
Encore un joli package npm est glob.
npm install glob
Il est très puissant et devrait couvrir tous vos recursing besoins.
Edit:
J'ai fait n'était pas parfaitement heureux avec glob, j'ai donc créé readdirp.
Je suis très confiant que son API permet de trouver des fichiers et des répertoires de manière récursive et application de filtres spécifiques très facilement.
Lire son la documentation pour avoir une meilleure idée de ce qu'il fait et de l'installer via:
npm install readdirp
Je recommande d'utiliser nœud-glob pour accomplir cette tâche.
Si vous souhaitez utiliser un package npm, clé est assez bonne.
MODIFIER (2018):
- On lire à travers ces derniers temps: L'auteur obsolète de ce forfait en 2015:
denodify
cela? Le rappel est déclenché plusieurs fois (de manière récursive). Donc, en utilisantQ.denodify(wrench.readdirRecursive)
renvoie uniquement le premier résultat.J'ai adoré la réponse de chjj ci-dessus et n'aurait pas été en mesure de créer ma version de la boucle parallèle sans que commencer.
J'ai créé un Résumé ainsi. Commentaires bienvenus. Je suis encore débutant dans le NodeJS royaume afin que est un, j'espère en savoir plus.
Utilisation nœud-dir pour obtenir exactement le résultat que vous aimez
Avec La Récursivité
Appel
/
mais à l'aide de lapath
module:path.join(searchPath, file)
. De cette façon, vous obtiendrez de bons chemins indépendant de l'OS.J'ai codé cette récemment, et pense qu'il serait bon de les partager ici. Le code fait usage de la async bibliothèque.
Vous pouvez l'utiliser comme ceci:
Une bibliothèque appelée Filehound est une autre option. Il recherche de manière récursive un répertoire donné (répertoire de travail par défaut). Il prend en charge divers filtres, des rappels, des promesses et de synchronisation des recherches.
Par exemple, rechercher le répertoire de travail courant pour tous les fichiers (à l'aide de rappels):
Ou de promesses et de spécifier un répertoire spécifique:
Consulter la documentation pour plus de cas d'utilisation et exemples d'utilisation: https://github.com/nspragg/filehound
Disclaimer: je suis l'auteur.
À l'aide async/await, cela devrait fonctionner:
Vous pouvez utiliser bluebird.Promisify ou ceci:
Voir mon autre réponse pour un générateur approche qui peut donner des résultats encore plus rapidement.
Découvrez la final-fs de la bibliothèque. Il fournit un
readdirRecursive
fonction:Autonome promesse de la mise en œuvre
Je suis en utilisant le when.js promesse de la bibliothèque dans cet exemple.
J'ai inclus un paramètre facultatif
includeDir
qui va inclure des répertoires dans le fichier de liste sitrue
.klaw et klaw-sync sont à envisager pour ce genre de chose. Ces faisaient partie de nœud-fs-extra.
Voici encore un autre mise en œuvre. Aucune des solutions ci-dessus ont tout de limiteurs d'effort, et donc, si votre structure de répertoire est vaste, ils vont tous thrash et, finalement, à court de ressources.
À l'aide d'une simultanéité de 50 fonctionne assez bien, et est presque aussi rapide que simple implémentations pour les petites structures de répertoire.
La recursive-readdir module dispose de cette fonctionnalité.
J'ai modifié Trevor âgées Promesse de réponse de travailler avec Bluebird
Pour le plaisir, voici une fonction de la version qui fonctionne avec highland.js les ruisseaux de la bibliothèque. Il a été co-écrit par Victor Vu.
À l'aide de Promesses (Q) afin de résoudre ce dans un style Fonctionnel:
Elle renvoie une promesse d'un tableau, de sorte que vous pouvez l'utiliser comme:
Je dois ajouter que la Promesse à base de sander bibliothèque à la liste.
À l'aide de bluebird promesse.coroutine:
Async
Sync
Async lisible
Remarque: les deux versions de suivre les liens symboliques (le même que l'original
fs.readdir
)Parce que tout le monde devrait écrire son propre, j'en ai fait une.
à pied(dir, cb, endCb)
cb(fichier)
endCb(err | null)
SALE
découvrez loaddir
https://npmjs.org/package/loaddir
npm install loaddir
Vous pouvez utiliser
fileName
au lieu debaseName
si vous avez besoin de l'extension ainsi.Un bonus supplémentaire est que pour regarder les fichiers et appeler la fonction de rappel de nouveau. Il y a des tonnes d'options de configuration pour le rendre extrêmement flexible.
J'ai juste refait la
guard
gemme de rubis à l'aide de loaddir dans peu de temps,C'est ma réponse. J'espère que ça peut aider quelqu'un.
Mon objectif est de faire de la recherche de routine peut s'arrêter n'importe où, et un fichier trouvé, dit la profondeur par rapport à la trajectoire initiale.
Voici une méthode récursive de récupérer tous les fichiers, y compris les sous-répertoires.
Un autre simple et utile
C'est la façon dont j'utilise le nodejs fs.readdir fonction récursive de la recherche d'un répertoire.
Disons que vous avez un chemin appelé '/base de données " dans votre nœud de projets de racine. Une fois cette promesse est résolu, il doit cracher un tableau de tous les fichiers sous '/base de données".
Encore une autre réponse, mais cette fois à l'aide de la Machine:
JS:
Pour Nœud de 10,3+, voici une pour les attendent solution:
L'avantage de cette solution est que vous pouvez commencer le traitement immédiatement les résultats; par exemple, il faut 12 secondes pour lire tous les fichiers dans mon répertoire de médias, mais si je le fais de cette façon je peux obtenir le premier résultat dans un délai de quelques millisecondes.
Il y a un module NPM pour cela:
mnp dree
Il se promène à travers toute l'arborescence du répertoire de cet objet et la retourne comme une chaîne ou un objet. À l'aide de son fichier de rappel vous permettra d'atteindre votre objectif.
Exemple:
Notez que si vous utilisez attendent, ce code doit être inclus dans une fonction async. Une promesse est retourné, de sorte que vous pouvez utiliser .alors() la méthode.
voici la code de travail. Selon votre condition. vous pouvez obtenir tous les fichiers et dossiers de manière récursive.
dans le chemin d'accès de donner à votre chemin d'accès au répertoire dans lequel vous souhaitez rechercher comme "c:\test"