Question Comment obtenez-vous une liste des noms de tous les fichiers présents dans un répertoire dans 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 une sortie qui est un tableau de noms de fichiers. Comment puis-je faire ceci?


629
2018-04-28 06:10


origine


Réponses:


Vous pouvez utiliser le fs.readdir ou fs.readdirSync méthodes

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 le premier est asynchrone, donc vous devez fournir une fonction de rappel qui sera exécutée lorsque le processus de lecture se termine.

La seconde est synchrone, elle renverra le nom de fichier array, mais elle arrêtera toute autre exécution de votre code jusqu'à la fin du processus de lecture.


831
2018-04-28 06:15



La réponse ci-dessus n'effectue pas de recherche récursive dans le répertoire. Voici ce que j'ai fait pour une recherche récursive (en utilisant node-walk: 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);
});

164
2018-04-27 07:35



L'OMI est le moyen le plus pratique de faire de telles tâches glob outil. Voici un paquet glob pour node.js. Installer avec

npm install glob

Utilisez ensuite un caractère générique pour faire correspondre les noms de fichiers (exemple extrait du site Web du package)

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.
})

156
2017-08-30 07:57



Obtenir des fichiers dans tous les sous-répertoires

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

73
2017-12-11 17:25



Voici une solution simple en utilisant seulement le natif fs et path modules:

// sync version
function walkSync(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}

ou version async (utilise fs.readdir au lieu):

// async version with basic error handling
function walk(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }
        files.forEach(function (name) {
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, stat);
            } else if (stat.isDirectory()) {
                walk(filePath, callback);
            }
        });
    });
}

Ensuite, vous appelez simplement (pour la version de synchronisation):

walkSync('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

ou version asynchrone:

walk('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

La différence réside dans la façon dont le nœud se bloque lors de l'exécution de l'E / S. Étant donné que l'API ci-dessus est la même, vous pouvez simplement utiliser la version asynchrone pour assurer une performance maximale.

Cependant, il y a un avantage à utiliser la version synchrone. Il est plus facile d'exécuter du code dès que la marche est terminée, comme dans la déclaration suivante après la marche. Avec la version asynchrone, vous aurez besoin d'un moyen supplémentaire de savoir quand vous avez terminé. Peut-être créer d'abord une carte de tous les chemins, puis les énumérer. Pour les scripts build / util simples (vs serveurs web haute performance), vous pouvez utiliser la version de synchronisation sans causer de dégâts.


49
2018-02-03 00:54



Utiliser les promesses avec ES7

Utilisation asynchrone avec mz / fs

le mz Le module fournit des versions promisifiées de la bibliothèque de nœuds principaux. Les utiliser est simple. Commencez par installer la bibliothèque ...

npm install mz

Alors...

const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
  .catch(err => console.error(err));

Vous pouvez également les écrire dans des fonctions asynchrones dans ES7:

async function myReaddir () {
  try {
    const file = await fs.readdir('./myDir/');
  }
  catch (err) { console.error( err ) }
};

Mise à jour pour la liste récursive

Certains des utilisateurs ont spécifié un désir de voir une liste récursive (mais pas dans la question) ... Utilisation fs-promise. C'est une enveloppe mince mz.

npm install fs-promise;

puis...

const fs = require('fs-promise');
fs.walk('./myDir').then(
    listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));

18
2018-05-30 18:48



Dépendances

var fs = require('fs');
var path = require('path');

Définition.

// String -> [String]
function fileList(dir) {
  return fs.readdirSync(dir).reduce(function(list, file) {
    var name = path.join(dir, file);
    var isDir = fs.statSync(name).isDirectory();
    return list.concat(isDir ? fileList(name) : [name]);
  }, []);
}

Usage.

var DIR = '/usr/local/bin';

// 1. List all files in DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]

// 2. List all file names in DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]

Veuillez noter que fileList est trop optimiste. Pour tout ce qui est sérieux, ajoutez un traitement d'erreur.


12
2017-11-13 03:31



Vous ne dites pas que vous voulez le faire de manière récursive, donc je suppose que vous n'avez besoin que des enfants directs du répertoire.

Exemple de code:

const fs = require('fs');
const path = require('path');

fs.readdirSync('your-directory-path')
  .filter((file) => fs.lstatSync(path.join(folder, file)).isFile());

9
2017-07-01 14:25



Charge fs:

const fs = require('fs');

Lire des fichiers async:

fs.readdir('./dir', function (err, files) {
    // "files" is an Array with files names
});

Lire des fichiers synchroniser:

var files = fs.readdirSync('./dir');

6
2017-09-13 17:12



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
2018-03-01 20:57



Pris l'approche générale de @ Hunan-Rostomyan, fait un peu plus concis et ajouté excludeDirsargument. Il serait trivial de prolonger avec includeDirs, suivez simplement le même schéma:

import * as fs from 'fs';
import * as path from 'path';

function fileList(dir, excludeDirs?) {
    return fs.readdirSync(dir).reduce(function (list, file) {
        const name = path.join(dir, file);
        if (fs.statSync(name).isDirectory()) {
            if (excludeDirs && excludeDirs.length) {
                excludeDirs = excludeDirs.map(d => path.normalize(d));
                const idx = name.indexOf(path.sep);
                const directory = name.slice(0, idx === -1 ? name.length : idx);
                if (excludeDirs.indexOf(directory) !== -1)
                    return list;
            }
            return list.concat(fileList(name, excludeDirs));
        }
        return list.concat([name]);
    }, []);
}

Exemple d'utilisation:

console.log(fileList('.', ['node_modules', 'typings', 'bower_components']));

3
2018-01-15 00:28