javascript - read - ¿Cómo se obtiene una lista de los nombres de todos los archivos presentes en un directorio en Node.js?
node js count files in directory (16)
Usando Promesas con ES7
Uso asíncrono con mz / fs
El módulo mz
proporciona versiones prometidas de la biblioteca de nodos centrales. 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 escribirlas 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) ... Use fs-promise
. Es una envoltura delgada alrededor de 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));
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 archivos. ¿Cómo puedo hacer esto?
Aquí hay una solución simple utilizando solo los módulos de path
y fs
nativos:
// 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 asíncrona (usa fs.readdir
en fs.readdir
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 solo llamas (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, puede usar la versión asíncrona para garantizar el máximo rendimiento.
Sin embargo, hay una ventaja de usar la versión síncrona. Es más fácil ejecutar un código tan pronto como se realiza la caminata, como en la siguiente declaración después de la caminata. Con la versión asíncrona, necesitaría alguna forma adicional de saber cuándo ha terminado. Quizás creando primero un mapa de todos los caminos, luego enumerándolos. Para los scripts de compilación / utilidad simples (frente a los servidores web de alto rendimiento), puede usar la versión de sincronización sin causar ningún daño.
Aquí hay una versión recursiva asíncrona.
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()
}
Carga fs
:
const fs = require(''fs'');
Leer archivos asíncronos :
fs.readdir(''./dir'', function (err, files) {
// "files" is an Array with files names
});
Leer archivos sincronizados :
var files = fs.readdirSync(''./dir'');
En mi opinión, la forma más conveniente de realizar estas tareas es utilizar una herramienta glob . Aquí hay un github.com/isaacs/node-glob global para node.js. Instalar con
npm install glob
Luego use el comodín para hacer coincidir los nombres de archivo (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.
})
Hice un módulo de nodo para automatizar esta tarea: mddir
Uso
nodo mddir "../relative/path/"
Para instalar: npm install mddir -g
Para generar rebajas para el directorio actual: mddir
Para generar para cualquier ruta absoluta: mddir / absolute / ruta
Para generar para una ruta relativa: mddir ~ / Documents / whatever.
El archivo md se genera en su directorio de trabajo.
Actualmente ignora los node_modules y las carpetas .git.
Solución de problemas
Si recibe el error ''nodo / r: No existe tal archivo o directorio'', el problema es que su sistema operativo usa diferentes finales de línea y mddir no puede analizarlos sin que usted establezca explícitamente el estilo de final de línea en Unix. Esto generalmente afecta a Windows, pero también a algunas versiones de Linux. La configuración de los finales de línea al estilo Unix debe realizarse dentro de la carpeta bin global de mddir npm.
Corrección de finales de línea
Obtenga la ruta de la carpeta bin npm con:
npm config get prefix
Cd en esa carpeta
brew install dos2unix
dos2unix lib / node_modules / mddir / src / mddir.js
Esto convierte los finales de línea a Unix en lugar de Dos
Luego ejecute normalmente con: node mddir "../relative/path/".
Ejemplo de estructura de archivos de rebaja generada ''directoryList.md''
|-- .bowerrc
|-- .jshintrc
|-- .jshintrc2
|-- Gruntfile.js
|-- README.md
|-- bower.json
|-- karma.conf.js
|-- package.json
|-- app
|-- app.js
|-- db.js
|-- directoryList.md
|-- index.html
|-- mddir.js
|-- routing.js
|-- server.js
|-- _api
|-- api.groups.js
|-- api.posts.js
|-- api.users.js
|-- api.widgets.js
|-- _components
|-- directives
|-- directives.module.js
|-- vendor
|-- directive.draganddrop.js
|-- helpers
|-- helpers.module.js
|-- proprietary
|-- factory.actionDispatcher.js
|-- services
|-- services.cardTemplates.js
|-- services.cards.js
|-- services.groups.js
|-- services.posts.js
|-- services.users.js
|-- services.widgets.js
|-- _mocks
|-- mocks.groups.js
|-- mocks.posts.js
|-- mocks.users.js
|-- mocks.widgets.js
No dices que quieres hacerlo recursivamente, así que asumo 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());
Obtener archivos en todos los subdirectorios.
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''))
Obtener nombres de archivos sorted
. Puede filtrar los resultados según una extension
específica como ''.txt''
, ''.jpg''
y así sucesivamente.
import * as fs from ''fs'';
import * as Path from ''path'';
function getFilenames(path, extension) {
return fs
.readdirSync(path)
.filter(
item =>
fs.statSync(Path.join(path, item)).isFile() &&
(extension === undefined || Path.extname(item) === extension)
)
.sort();
}
Puede utilizar los métodos fs.readdir
o fs.readdirSync
.
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 asíncrono, 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 adicional de su código hasta que finalice el proceso de lectura.
Sin embargo, la respuesta anterior no realiza una búsqueda recursiva en el directorio. Esto es lo que hice para una búsqueda recursiva (usando 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);
});
Tomó el enfoque general de @ Hunan-Rostomyan, lo hizo un poco más conciso y agregó el argumento excludeDirs
. Sería trivial extender con includeDirs
, solo sigue el mismo patrón:
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]);
}, []);
}
Ejemplo de uso:
console.log(fileList(''.'', [''node_modules'', ''typings'', ''bower_components'']));
Utilice el npm
list-contents npm
. Lee los contenidos y sub-contenidos del directorio dado y devuelve la lista de rutas de archivos y carpetas.
const list = require(''list-contents'');
list("./dist",(o)=>{
if(o.error) throw o.error;
console.log(''Folders: '', o.dirs);
console.log(''Files: '', o.files);
});
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 seria, agregue algún manejo de errores.
function getFilesRecursiveSync(dir, fileList, optionalFilterFunction) {
if (!fileList) {
grunt.log.error("Variable ''fileList'' is undefined or NULL.");
return;
}
var files = fs.readdirSync(dir);
for (var i in files) {
if (!files.hasOwnProperty(i)) continue;
var name = dir + ''/'' + files[i];
if (fs.statSync(name).isDirectory()) {
getFilesRecursiveSync(name, fileList, optionalFilterFunction);
} else {
if (optionalFilterFunction && optionalFilterFunction(name) !== true)
continue;
fileList.push(name);
}
}
}