Рекурсивное чтение папки в NodeJS
Одной из самых частых задач при работе с каталогами (директориями) в NodeJS является их рекурсивное чтение. Что это такое? Например, у вас есть папка, а в ней еще папка, а в ней еще - и так далее. И Вам необходимо прочитать содержимое корневой папки и всех дочерних, причем уровень вложенности может быть сколь угодно произвольным. Для того, чтобы вывести содержимое всех папок как раз и понадобится рекурсия - вызов функцией самой себя.
В примере кода для NodeJS ниже я покажу Вам как этого можно добиться.
Первый пример
/**
* Принимает функцию вида (err, value) => {}
* и возвращает ее в виде обещания (промиса).
*/
const { promisify } = require('util');
/**
* в комментарии к коду ниже есть описание данной функции
*/
const { resolve } = require('path');
const fs = require('fs');
const readdir = promisify(fs.readdir); // промифицирует функцию readdir
const stat = promisify(fs.stat); // тоже самое что и выше, только c stat
/**
* Рекурсивно обходит папку и возвращает все найденные в ней файлы
* в виде одномерного массива абсолютный путей
*
* @param {string} dir Корневая папка
* @returns {Promise<string[]>} массив строк - путей к файлам
*/
async function getFiles(dir) {
// асинхронно читает содержимое директории
const subfolders = await readdir(dir);
// возвращает список всех путей к файлам
const files = await Promise.all(subfolders.map(async (subfolder) => {
// преобразует путь к файлу из относительного в абсолютный
const res = resolve(dir, subfolder);
// проверяет директория или файл
// если директория - рекурсивно вызывает саму себя
// в противном случае возвращает файл в массив
return (await stat(res)).isDirectory() ? getFiles(res) : res;
}));
// преобразует многомерный полученный массив путей в одномерный
return files.reduce((a, f) => a.concat(f), []);
}
// запускаем с текущей директорией
getFiles(__dirname)
.then(files => console.log(files)) // выводим массив путей
.catch(e => console.error(e)); // или ошибки в консоль
Второй пример:
const { resolve } = require('path');
const { readdir } = require('fs').promises; // промифицированная версия функций из метода
/**
*
* @param {stirng} dir папка, с которой начинается сканирование
* @returns {Promise<stirng[]>}
*/
async function getFiles(dir) {
// читаем содержимое директории
const dirents = await readdir(dir, { withFileTypes: true });
// как и в прошлом примере проходимся по папкам
// и, при необходимости рекурсивно вызываем функцию
const files = await Promise.all(dirents.map((dirent) => {
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
// преобразуем массив файлов в одномерный
return Array.prototype.concat(...files);
}
// тестируем
getFiles(__dirname)
.then(files => console.log(files))
.catch(err => console.error(err))
Вот таким образом, можно рекурсивно обойти все директории и найти полные пути ко всем файлам в NodeJS.
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.