1291 votes

Comment obtenir la liste des noms de tous les fichiers présents dans un répertoire en Node.js ?

J'essaie d'obtenir une liste des noms de tous les fichiers présents dans un répertoire en utilisant Node.js. Je veux un résultat qui soit un tableau de noms de fichiers. Comment puis-je faire cela ?

12 votes

fs.readdir fonctionne, mais ne peut pas utiliser des motifs globaux de noms de fichiers tels que ls /tmp/*core* . Vérifier github.com/isaacs/node-glob . Les globs peuvent même effectuer des recherches dans des sous-répertoires.

1 votes

Vérifier les NPM readdir-recursive mais si vous cherchez les noms des fichiers dans les sous-répertoires, vous pouvez également utiliser le module

0 votes

1756voto

CMS Points 315406

Vous pouvez utiliser le fs.readdir o fs.readdirSync des méthodes. fs est inclus dans le noyau de Node.js, il n'est donc pas nécessaire d'installer quoi que ce soit.

fs.readdir

const testFolder = './tests/';
const fs = require('fs');

fs.readdir(testFolder, (err, files) => {
  files.forEach(file => {
    console.log(file);
  });
});

fs.readdirSync

const testFolder = './tests/';
const fs = require('fs');

fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
});

La différence entre les deux méthodes est que la première est asynchrone, vous devez donc fournir une fonction de rappel qui sera exécutée lorsque le processus de lecture se terminera.

La seconde est synchrone, elle renvoie le tableau des noms de fichiers, mais elle interrompt l'exécution de votre code jusqu'à ce que le processus de lecture se termine.

238 votes

Remarque : readdir montre également noms des répertoires . Pour les filtrer, utilisez fs.stat(path, callback(err, stats)) y stats.isDirectory() .

5 votes

Je dois ajouter que vous devriez probablement opter pour readdire parce que vous ne voulez pas bloquer les entrées-sorties dans le nœud.

5 votes

@user3705055 sauf si vous utilisez gulp pour lire un répertoire de fichiers dépendants de l'ordre des sources et les compiler en un seul exécutable.

248voto

KFL Points 1082

IMO : la façon la plus pratique d'effectuer ce type de tâches est d'utiliser un fichier glob outil. Voici un paquet global pour node.js. Installer avec

npm install glob

Utilisez ensuite un joker pour faire correspondre les noms de fichiers (exemple tiré de la page d'accueil du paquet). site web )

var glob = require("glob")

// options is optional
glob("**/*.js", options, function (er, files) {
  // files is an array of filenames.
  // If the `nonull` option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
})

Si vous envisagez d'utiliser globby Voici un exemple de recherche de tout fichier xml se trouvant dans le dossier courant

var globby = require('globby');

const paths = await globby("**/*.xml");

5 votes

C'était la meilleure solution pour moi car je voulais spécifier le type de fichier plus facilement que les comparaisons de chaînes. Je vous remercie.

0 votes

Je l'aime bien aussi parce que le globbing est presque une compétence fondamentale dans node. Si vous voulez juste récupérer les noms de fichiers, passez une commande cwd dans l'objet des options.

1 votes

Comment obtenir les résultats de glob en dehors de lui-même ? Par exemple, je veux console.log les résultats, mais pas à l'intérieur glob() ?

187voto

Ruben Tan Points 1147

La réponse ci-dessus n'effectue cependant pas de recherche récursive dans le répertoire. Voici ce que j'ai fait pour une recherche récursive (en utilisant marche-nœud : npm install walk )

var walk    = require('walk');
var files   = [];

// Walker options
var walker  = walk.walk('./test', { followLinks: false });

walker.on('file', function(root, stat, next) {
    // Add this file to the list of files
    files.push(root + '/' + stat.name);
    next();
});

walker.on('end', function() {
    console.log(files);
});

4 votes

Fs.readdirSync est une meilleure alternative native créée spécialement pour cela.

38 votes

Fs.readdirSync ne va pas dans les sous-répertoires malheureusement, à moins que vous ne souhaitiez écrire votre propre routine pour faire cela, ce qui n'est pas le cas étant donné qu'il existe déjà des modules npm pour résoudre ce problème.

7 votes

Voici un lien vers le repo github de la marche + la documentation : github.com/coolaj86/node-walk

110voto

Tito100 Points 349

Obtenir les fichiers dans tous les sous-répertoires

const fs=require('fs');

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.push(name);
        }
    }
    return files_;
}

console.log(getFiles('path/to/dir'))

4 votes

Pourquoi if (typeof files_ === 'undefined') files_=[]; ? il suffit de faire var files_ = files_ || []; au lieu de files_ = files_ || []; .

4 votes

Vous avez oublié d'ajouter var fs = require('fs'); au début de getFiles .

0 votes

Il s'agit d'une méthode récursive. Elle ne prend pas en charge les structures de dossiers très profondes, ce qui entraînerait un dépassement de pile.

5voto

Voici une version récursive asynchrone.

    function ( path, callback){
     // the callback gets ( err, files) where files is an array of file names
     if( typeof callback !== 'function' ) return
     var
      result = []
      , files = [ path.replace( /\/\s*$/, '' ) ]
     function traverseFiles (){
      if( files.length ) {
       var name = files.shift()
       fs.stat(name, function( err, stats){
        if( err ){
         if( err.errno == 34 ) traverseFiles()
    // in case there's broken symbolic links or a bad path
    // skip file instead of sending error
         else callback(err)
        }
        else if ( stats.isDirectory() ) fs.readdir( name, function( err, files2 ){
         if( err ) callback(err)
         else {
          files = files2
           .map( function( file ){ return name + '/' + file } )
           .concat( files )
          traverseFiles()
         }
        })
        else{
         result.push(name)
         traverseFiles()
        }
       })
      }
      else callback( null, result )
     }
     traverseFiles()
    }

4 votes

Prenez l'habitude d'ajouter des points-virgules à la fin de vos déclarations. Vous ne pouvez pas minifier le code autrement. Néanmoins, merci pour la contribution asynchrone tant attendue.

2 votes

HAHAHAHA cela ne fait pas partie de la spécification, c'est juste une personne au hasard qui appelle son style de linting préféré "standardjs". Les points-virgules sont une bonne pratique, surtout en Javascript, pour maintenir la clarté du code. Sinon, vous et votre équipe devez mémoriser les règles de insertion automatique de points-virgules et je sais qu'au moins le développeur JS moyen là où je travaille n'est pas aussi diligent.

3 votes

@user2867288 Mais puisque l'ASI existe, nous pouvons l'utiliser, non ? J'utilise eslint et prettier pour formater mon code en le sauvegardant régulièrement et l'insertion de points-virgules n'est pas un problème.

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