Pregunta ¿Cómo se obtiene una lista de los nombres de todos los archivos presentes en un directorio en Node.js?


Estoy tratando de obtener una lista de los nombres de todos los archivos presentes en un directorio usando Node.js. Quiero salida que es una matriz de nombres de archivo. ¿Cómo puedo hacer esto?


629
2018-04-28 06:10


origen


Respuestas:


Puedes usar el fs.readdir o fs.readdirSync métodos.

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 diferencia entre los dos métodos es que el primero es asincrónico, por lo que debe proporcionar una función de devolución de llamada que se ejecutará cuando finalice el proceso de lectura.

El segundo es sincrónico, devolverá la matriz de nombre de archivo, pero detendrá cualquier ejecución posterior de su código hasta que finalice el proceso de lectura.


831
2018-04-28 06:15



La respuesta anterior no realiza una búsqueda recursiva en el directorio. Esto es lo que hice para una búsqueda recursiva (usando caminar por el nodo: 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



IMO la forma más conveniente para hacer tales tareas es usar un glob herramienta. Aquí está un paquete glob para node.js. Instalar con

npm install glob

A continuación, utilice la tarjeta salvaje para que coincida con los nombres de los archivos (ejemplo tomado del sitio web del paquete)

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



Obtener archivos en todos los subdires

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



Aquí hay una solución simple que usa solo el nativo fs y path módulos:

// 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);
        }
    });
}

o versión asincrónica (usos fs.readdir en lugar):

// 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);
            }
        });
    });
}

Entonces simplemente llama (para la versión de sincronización):

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

o versión asíncrona:

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

La diferencia está en cómo se bloquea el nodo mientras se realiza el IO. Dado que la API anterior es la misma, puedes usar la versión asíncrona para garantizar el máximo rendimiento.

Sin embargo, hay una ventaja al usar la versión síncrona. Es más fácil ejecutar algún código tan pronto como finaliza la caminata, como en la siguiente declaración después de la caminata. Con la versión asíncrona, necesitarás una forma adicional de saber cuándo termines. Quizás crear primero un mapa de todos los caminos y luego enumerarlos. Para scripts simples de compilación / utilidad (en comparación con los servidores web de alto rendimiento), puede utilizar la versión de sincronización sin causar ningún daño.


49
2018-02-03 00:54



Usando Promesas con ES7

Uso asincrónico con mz / fs

los mz el módulo proporciona versiones promisificadas de la biblioteca del nodo central. Usarlos es simple. Primero instala la biblioteca ...

npm install mz

Entonces...

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

Alternativamente, puede escribirlos en funciones asíncronas en ES7:

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

Actualización para listado recursivo

Algunos de los usuarios han especificado el deseo de ver una lista recursiva (aunque no en la pregunta) ... Usar fs-promise. Es una capa delgada alrededor mz.

npm install fs-promise;

entonces...

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



Dependencias

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

Definición.

// 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]);
  }, []);
}

Uso.

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', ...]

Tenga en cuenta que fileList es demasiado optimista Para cualquier cosa grave, agregue un poco de manejo de errores.


12
2017-11-13 03:31



No dices que quieres hacerlo recursivamente así que supongo que solo necesitas hijos directos del directorio.

Código de muestra:

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



Carga fs:

const fs = require('fs');

Leer archivos asincrónico:

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

Leer archivos sincronización:

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

6
2017-09-13 17:12



Aquí hay una versión recursiva asincrónica.

    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