Как получить список имен всех файлов в директории в Node.js?
Я пытаюсь получить список имен всех файлов, находящихся в директории, используя Node.js. Мне нужен вывод в виде массива имен файлов. Как я могу это сделать?
5 ответ(ов)
Чтобы получить файлы во всех подкаталогах в Node.js, вы можете использовать следующий код:
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'));
Этот скрипт определяет функцию getFiles
, которая принимает путь к директории (dir
) и массив файлов (files_
). Если массив не передан, он инициализируется как пустой массив. Сначала функция считывает содержимое директории с помощью fs.readdirSync
. Затем она проходит по каждому элементу и проверяет, является ли он директорией с помощью fs.statSync
. Если это директория, функция вызывает сама себя рекурсивно, передавая новый путь. Если это файл, его путь добавляется в массив files_
. В конце функция возвращает массив с полными путями ко всем найденным файлам.
Просто замените 'path/to/dir'
на нужный вам путь к директории, и вы получите список всех файлов внутри указанной директории и ее подкаталогов.
Вот простое решение, использующее только встроенные модули fs
и path
:
// синхронная версия
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);
}
});
}
или асинхронная версия (использует fs.readdir
вместо этого):
// асинхронная версия с базовой обработкой ошибок
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);
}
});
});
}
После этого вы просто вызываете (для синхронной версии):
walkSync('path/to/root/dir', function(filePath, stat) {
// делаем что-то с "filePath"...
});
или для асинхронной версии:
walk('path/to/root/dir', function(filePath, stat) {
// делаем что-то с "filePath"...
});
Разница в том, как Node.js блокирует выполнение во время операций ввода-вывода. Так как API выше аналогичен, вы можете просто использовать асинхронную версию для обеспечения максимальной производительности.
Однако есть одно преимущество у синхронной версии. Проще выполнить некоторый код сразу после завершения обхода, как в следующем операторе после обхода. С асинхронной версией вам необходимо использовать дополнительный способ, чтобы узнать, когда вы завершили. Возможно, стоит сначала создать карту всех путей, а затем перебрать их. Для простых скриптов сборки/утилит (в отличие от высокопроизводительных веб-серверов) вы можете использовать синхронную версию, не вызывая проблем.
Нерекурсивная версия
Вы не упомянули, что хотите сделать это рекурсивно, поэтому я предполагаю, что вам нужны только непосредственные дочерние элементы директории.
Пример кода:
const fs = require('fs');
const path = require('path');
fs.readdirSync('путь-до-вашей-директории')
.filter((file) => fs.lstatSync(path.join('путь-до-вашей-директории', file)).isFile());
Этот код считывает содержимое указанной директории и фильтрует только файлы, игнорируя поддиректории.
Зависимости.
var fs = require('fs');
var path = require('path');
Определение.
// 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]);
}, []);
}
Использование.
var DIR = '/usr/local/bin';
// 1. Получить список всех файлов в DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]
// 2. Получить имена всех файлов в DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]
Обратите внимание, что fileList
слишком оптимистичен в своем подходе. Для реального использования обязательно добавьте обработку ошибок.
Для загрузки модуля fs
вы можете использовать следующий код:
const fs = require('fs');
Для асинхронного чтения файлов из директории используйте fs.readdir
, как показано ниже:
fs.readdir('./dir', function (err, files) {
// "files" - это массив с именами файлов
});
Если вам нужно синхронно прочитать файлы, вы можете использовать fs.readdirSync
следующим образом:
var files = fs.readdirSync('./dir');
Этот код в первом случае выполняет операции асинхронно, что позволяет вашему приложению не блокироваться, а во втором случае — выполняет чтение синхронно, что может быть полезно в определённых сценариях.
Использование async/await с циклом forEach
Запись в файлы в Node.js
Функция map для объектов (вместо массивов)
Как получить полный объект в console.log() Node.js, а не '[Object]'?
Как прочитать JSON-файл в память сервера?