Как получить список всех файлов в папке с помощью Node.js?
Проблема и её решение
Ваш код не работает, потому что fs.readdir — асинхронная функция. Она не возвращает результат напрямую, а принимает колбэк или возвращает промис (в версиях Node.js 10+). Когда вы пытаетесь присвоить результат переменной files, вы получаете undefined, так как операция ещё не завершилась.
Вот три основных способа получить список файлов:
1. Асинхронный метод с колбэком (классический)
const fs = require('fs');
const path = require('path');
const folderPath = './images';
fs.readdir(folderPath, (err, files) => {
if (err) {
console.error('Ошибка чтения папки:', err);
return;
}
console.log('Все содержимое папки:', files);
// Фильтруем только файлы (исключаем папки)
const onlyFiles = files.filter(file => {
const fullPath = path.join(folderPath, file);
return fs.statSync(fullPath).isFile();
});
console.log('Только файлы:', onlyFiles);
// Добавляем полный путь
const filesWithPath = onlyFiles.map(file => path.join(folderPath, file));
console.log('Файлы с полным путём:', filesWithPath);
});
2. Асинхронный метод с промисами (современный)
const fs = require('fs').promises;
const path = require('path');
async function listFiles(folderPath) {
try {
const items = await fs.readdir(folderPath);
console.log('Все содержимое папки:', items);
// Фильтруем только файлы
const files = [];
for (const item of items) {
const fullPath = path.join(folderPath, item);
const stat = await fs.stat(fullPath);
if (stat.isFile()) {
files.push(item);
}
}
console.log('Только файлы:', files);
// С полным путём
const filesWithPath = files.map(file => path.join(folderPath, file));
console.log('Файлы с полным путём:', filesWithPath);
return filesWithPath;
} catch (err) {
console.error('Ошибка:', err);
}
}
// Использование
listFiles('./images').then(files => {
console.log('Получено файлов:', files.length);
});
3. Синхронный метод (простой, но блокирующий)
const fs = require('fs');
const path = require('path');
const folderPath = './images';
try {
const items = fs.readdirSync(folderPath);
console.log('Все содержимое папки:', items);
// Фильтруем только файлы
const onlyFiles = items.filter(item => {
const fullPath = path.join(folderPath, item);
return fs.statSync(fullPath).isFile();
});
console.log('Только файлы:', onlyFiles);
// С полным путём
const filesWithPath = onlyFiles.map(file => path.join(folderPath, file));
console.log('Файлы с полным путём:', filesWithPath);
// Дальше можно работать с массивом
filesWithPath.forEach(file => {
console.log('Обрабатываю:', file);
});
} catch (err) {
console.error('Ошибка:', err);
}
Рекомендации
- Для небольших скриптов — используйте
readdirSync, это проще и понятнее новичкам. - Для production-кода — используйте асинхронные методы с промисами (
fs.promises.readdir), чтобы не блокировать event loop. - Всегда проверяйте ошибки — папка может не существовать, файлы могут быть заблокированы и т.д.
- Используйте
path.joinдля корректного формирования путей (это работает на Windows, Linux и macOS).
Теперь ваш код будет работать правильно!
<<Альтернативный подход: использование рекурсии для вложенных папок
Если вам нужно получить список всех файлов не только в одной папке, но и во всех вложенных подпапках, можно написать рекурсивную функцию:
const fs = require('fs').promises;
const path = require('path');
async function getAllFiles(dir) {
const items = await fs.readdir(dir, { withFileTypes: true });
const files = [];
for (const item of items) {
const fullPath = path.join(dir, item.name);
if (item.isDirectory()) {
// Рекурсивно заходим в подпапку
const subFiles = await getAllFiles(fullPath);
files.push(...subFiles);
} else if (item.isFile()) {
files.push(fullPath);
}
}
return files;
}
// Использование
getAllFiles('./images').then(files => {
console.log('Все файлы (включая вложенные):', files);
});
Обратите внимание на опцию { withFileTypes: true } — она возвращает объекты fs.Dirent, у которых есть методы isFile() и isDirectory(). Это избавляет от необходимости вызывать fs.stat для каждого элемента, что значительно ускоряет работу с большими папками.
Также существуют готовые библиотеки, например glob или fast-glob, которые позволяют получать списки файлов по маске (например, только .jpg файлы). Но для базовых задач описанных выше методов вполне достаточно.
Ответов пока нет.
Войдите чтобы оставить ответ