Как получить список файлов в Node.js: методы, примеры, оптимизация

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Node.js-разработчики, желающие улучшить свои навыки работы с файловой системой.
  • Студенты и начинающие веб-разработчики, изучающие Node.js и его функционал.
  • Практикующие разработчики, которые ищут оптимальные методы обработки файлов в своих приложениях.

    Работа с файлами — хлеб насущный для любого Node.js-разработчика. Получить список файлов в директории — казалось бы, простая задача, но стоит копнуть глубже, и мы обнаружим целый арсенал методов и подходов, каждый со своими нюансами. От классического fs.readdir до современных promise-based API — Node.js предлагает множество инструментов для эффективного взаимодействия с файловой системой. В этой статье мы разберем все ключевые методы получения списка файлов, их преимущества, особенности применения и приведем практические примеры для типичных сценариев. 💻

Если вам интересно не просто узнать о методах работы с файлами, но и научиться создавать полноценные веб-приложения на Node.js, обратите внимание на Обучение веб-разработке от Skypro. Курс построен на практических задачах — вы освоите не только файловые операции, но и полный стек технологий для создания современных веб-сервисов. Преподаватели-практики помогут избежать типичных ошибок и научат писать эффективный и поддерживаемый код.

Основные методы Node.js для получения списка файлов

Node.js предоставляет несколько способов получения списка файлов в директории через встроенный модуль fs (file system). Понимание различных API и их особенностей поможет выбрать оптимальный подход для конкретной задачи.

Рассмотрим основные методы:

Метод Тип Особенности Версия Node.js
fs.readdir Асинхронный с колбэками Не блокирует поток выполнения Все версии
fs.readdirSync Синхронный Блокирует поток до завершения операции Все версии
fs.promises.readdir Асинхронный с промисами Современный подход с поддержкой async/await 10.0.0+
Библиотека glob Зависит от реализации Поддержка паттернов для фильтрации Внешний пакет

Прежде чем мы погрузимся в детали, важно понимать базовую структуру путей в Node.js. Для обработки путей рекомендуется использовать модуль path, который обеспечивает кроссплатформенную совместимость:

JS
Скопировать код
const path = require('path');

// Построение абсолютного пути к директории
const directoryPath = path.join(__dirname, 'target_directory');

Выбор метода зависит от нескольких факторов:

  • Сложность приложения — для небольших скриптов подойдет синхронный подход, для высоконагруженных приложений — асинхронный
  • Структура кода — современные приложения часто используют async/await, что делает промисы предпочтительнее колбэков
  • Требования к обработке ошибок — промисы обеспечивают более элегантный способ обработки ошибок
  • Версия Node.js — не все API доступны в старых версиях

Теперь давайте подробнее рассмотрим каждый подход, начиная с классических методов.

Пошаговый план для смены профессии

Синхронный и асинхронный подходы с fs.readdir

Node.js предоставляет как синхронные, так и асинхронные методы для работы с файловой системой. Разница между ними критична для производительности приложения. 🚀

Начнем с асинхронного метода fs.readdir. Он не блокирует событийный цикл Node.js, что критически важно для поддержания отзывчивости приложения:

JS
Скопировать код
const fs = require('fs');
const path = require('path');

const directoryPath = path.join(__dirname, 'example');

fs.readdir(directoryPath, (err, files) => {
if (err) {
return console.log('Ошибка при чтении директории: ' + err);
} 

console.log('Файлы в директории:');
files.forEach(file => {
console.log(file);
});
});

console.log('Это выполнится до завершения чтения директории!');

Синхронный вариант fs.readdirSync блокирует выполнение до завершения операции чтения директории:

JS
Скопировать код
const fs = require('fs');
const path = require('path');

const directoryPath = path.join(__dirname, 'example');

try {
const files = fs.readdirSync(directoryPath);
console.log('Файлы в директории:');
files.forEach(file => {
console.log(file);
});
} catch (err) {
console.log('Ошибка при чтении директории: ' + err);
}

console.log('Это выполнится только после завершения чтения директории');

Максим Петров, lead-разработчик бэкенда

На старте карьеры я столкнулся с неприятным инцидентом в production. Мы разрабатывали сервис для обработки пользовательских файлов, и я использовал fs.readdirSync для каталога с тысячами файлов. В час пик наш сервис начал "падать" по таймауту. Диагностика показала, что синхронная операция блокировала event loop на несколько секунд, что приводило к отказу в обслуживании новых запросов.

После рефакторинга на fs.readdir с правильной обработкой очередей задач, производительность выросла в 8 раз, а таймауты исчезли. Этот опыт научил меня относиться к выбору синхронных/асинхронных методов не как к вопросу удобства кода, а как к критическому архитектурному решению.

Вот основные отличия этих подходов:

Характеристика fs.readdir (асинхронный) fs.readdirSync (синхронный)
Блокировка потока Не блокирует Блокирует до завершения
Обработка результата Через колбэк Возвращает значение напрямую
Обработка ошибок Первый аргумент колбэка Try-catch блок
Подходит для Сервисы, API, интерактивные приложения Скрипты, утилиты, инициализация
Производительность при большом количестве файлов Высокая Низкая (блокирует event loop)

Оба метода принимают дополнительный параметр options, который позволяет настроить формат возвращаемых данных:

JS
Скопировать код
fs.readdir(directoryPath, { withFileTypes: true }, (err, files) => {
if (err) throw err;

files.forEach(dirent => {
if (dirent.isFile()) {
console.log(`${dirent.name} – это файл`);
} else if (dirent.isDirectory()) {
console.log(`${dirent.name} – это директория`);
}
});
});

Опция withFileTypes возвращает массив объектов Dirent вместо массива строк, что позволяет получить дополнительную информацию о каждом элементе без выполнения дополнительных операций stat.

Выбирая между синхронным и асинхронным подходами, руководствуйтесь следующими принципами:

  • Используйте синхронные методы только при инициализации приложения или в простых скриптах
  • В веб-серверах, API и других высоконагруженных сервисах всегда используйте асинхронные методы
  • Если требуется последовательная обработка файлов, используйте асинхронные методы в сочетании с async/await или библиотеками для управления потоком выполнения

Работа с fs.promises для современного кода

С версии Node.js 10.0.0 появился модуль fs.promises, который предоставляет API на основе промисов для работы с файловой системой. Этот подход значительно улучшает читаемость кода и упрощает обработку ошибок по сравнению с традиционными колбэками. 🔄

Базовый пример получения списка файлов с использованием fs.promises:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function getFilesList(directoryPath) {
try {
const files = await fs.readdir(directoryPath);
console.log('Файлы в директории:');
files.forEach(file => {
console.log(file);
});
return files;
} catch (err) {
console.error('Ошибка при чтении директории:', err);
throw err;
}
}

// Использование функции
getFilesList(path.join(__dirname, 'example'))
.then(files => console.log(`Всего файлов: ${files.length}`))
.catch(err => console.error('Произошла ошибка:', err));

Преимущества использования fs.promises по сравнению с традиционным подходом:

  • Упрощение логики асинхронного кода — возможность использовать async/await делает код более линейным и понятным
  • Эффективная обработка ошибок — используя конструкцию try-catch вместо проверки ошибки в колбэке
  • Простота композиции — легко комбинировать несколько асинхронных операций
  • Лучшая поддержка параллельного выполнения — с помощью Promise.all можно обрабатывать группы файлов параллельно

Для получения расширенной информации о файлах также можно использовать опцию withFileTypes:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function getFilesDetails(directoryPath) {
try {
const dirents = await fs.readdir(directoryPath, { withFileTypes: true });

const files = dirents
.filter(dirent => dirent.isFile())
.map(dirent => dirent.name);

const directories = dirents
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);

return { files, directories };
} catch (error) {
console.error('Ошибка при чтении директории:', error);
throw error;
}
}

getFilesDetails(path.join(__dirname, 'example'))
.then(result => {
console.log('Файлы:', result.files);
console.log('Директории:', result.directories);
})
.catch(err => console.error('Ошибка:', err));

Для получения подробной информации о каждом файле можно комбинировать readdir и stat:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function getFilesWithStats(directoryPath) {
try {
const files = await fs.readdir(directoryPath);

const fileStats = await Promise.all(
files.map(async filename => {
const filePath = path.join(directoryPath, filename);
const stats = await fs.stat(filePath);
return {
name: filename,
size: stats.size,
isDirectory: stats.isDirectory(),
created: stats.birthtime,
modified: stats.mtime
};
})
);

return fileStats;
} catch (error) {
console.error('Ошибка при чтении файлов:', error);
throw error;
}
}

getFilesWithStats(path.join(__dirname, 'example'))
.then(filesInfo => console.log(filesInfo))
.catch(err => console.error('Ошибка:', err));

Использование промисов особенно удобно при последовательной обработке файлов или когда необходимо выполнить дополнительные асинхронные операции для каждого файла. Например, чтение содержимого каждого файла:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function readAllTextFiles(directoryPath) {
try {
const files = await fs.readdir(directoryPath);
const textFiles = files.filter(file => file.endsWith('.txt'));

const contents = await Promise.all(
textFiles.map(async file => {
const content = await fs.readFile(path.join(directoryPath, file), 'utf8');
return { name: file, content };
})
);

return contents;
} catch (error) {
console.error('Ошибка при чтении файлов:', error);
throw error;
}
}

readAllTextFiles(path.join(__dirname, 'example'))
.then(filesContents => {
filesContents.forEach(file => {
console.log(`Файл: ${file.name}`);
console.log(`Содержимое: ${file.content}`);
console.log('---');
});
})
.catch(err => console.error('Ошибка:', err));

Алексей Сорокин, архитектор Node.js-приложений

Когда мы переписывали микросервис обработки изображений для крупного фотохостинга, замена колбэков на промисы привела к неожиданному результату. Код не только стал чище и понятнее, но и количество ошибок при деплое снизилось на 43%.

Самым показательным кейсом был рекурсивный обход директорий с изображениями: с колбэками код превращался в "ёлочку" из вложенных функций, а обработка ошибок дублировалась на каждом уровне. Переход на fs.promises с async/await сократил код на 30% и сделал отлов ошибок централизованным. Важный урок: современный синтаксис — это не просто "сахар", а инструмент повышения надежности.

Фильтрация и обработка полученных файлов

Получение списка файлов часто является лишь первым шагом. Типичные задачи включают фильтрацию по расширениям, сортировку, группировку и другие операции обработки. Рассмотрим наиболее распространенные подходы к фильтрации и обработке файлов. 🔍

Начнем с базовой фильтрации по расширению файла:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function getFilesByExtension(directoryPath, extension) {
try {
const files = await fs.readdir(directoryPath);
// Фильтруем файлы по расширению
return files.filter(file => path.extname(file).toLowerCase() === `.${extension.toLowerCase()}`);
} catch (error) {
console.error('Ошибка при чтении директории:', error);
throw error;
}
}

// Получение всех JavaScript файлов
getFilesByExtension(path.join(__dirname, 'project'), 'js')
.then(jsFiles => console.log('JavaScript файлы:', jsFiles))
.catch(err => console.error('Ошибка:', err));

Для более сложной фильтрации, например, по шаблонам (glob patterns), можно использовать специализированные библиотеки, такие как glob или fast-glob:

JS
Скопировать код
const glob = require('glob');
const util = require('util');
const globPromise = util.promisify(glob);

async function findFilesByPattern(pattern) {
try {
// Пример шаблона: './src/**/*.js'
return await globPromise(pattern);
} catch (error) {
console.error('Ошибка при поиске файлов:', error);
throw error;
}
}

// Найти все .js файлы во всех подпапках src
findFilesByPattern('./src/**/*.js')
.then(files => console.log('Найденные JS файлы:', files))
.catch(err => console.error('Ошибка:', err));

Часто требуется сортировка файлов по различным критериям:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function getSortedFiles(directoryPath, sortBy = 'name') {
try {
const files = await fs.readdir(directoryPath);

// Получаем статистику для каждого файла
const filesWithStats = await Promise.all(
files.map(async filename => {
const filePath = path.join(directoryPath, filename);
const stats = await fs.stat(filePath);
return { 
name: filename,
path: filePath,
size: stats.size,
created: stats.birthtime,
modified: stats.mtime
};
})
);

// Сортируем по выбранному критерию
switch (sortBy) {
case 'size':
return filesWithStats.sort((a, b) => a.size – b.size);
case 'created':
return filesWithStats.sort((a, b) => a.created – b.created);
case 'modified':
return filesWithStats.sort((a, b) => a.modified – b.modified);
case 'name':
default:
return filesWithStats.sort((a, b) => a.name.localeCompare(b.name));
}
} catch (error) {
console.error('Ошибка при получении или сортировке файлов:', error);
throw error;
}
}

// Получить файлы, отсортированные по размеру (от меньшего к большему)
getSortedFiles(path.join(__dirname, 'documents'), 'size')
.then(files => {
console.log('Файлы по размеру:');
files.forEach(file => {
console.log(`${file.name} – ${(file.size / 1024).toFixed(2)} KB`);
});
})
.catch(err => console.error('Ошибка:', err));

Группировка файлов по типам или другим критериям также является распространенной задачей:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function groupFilesByType(directoryPath) {
try {
const files = await fs.readdir(directoryPath);

// Объект для группировки файлов
const groupedFiles = {};

files.forEach(file => {
// Получаем расширение файла
const ext = path.extname(file).toLowerCase().replace('.', '') || 'unknown';

// Инициализируем массив для этого типа, если еще не существует
if (!groupedFiles[ext]) {
groupedFiles[ext] = [];
}

// Добавляем файл в соответствующую группу
groupedFiles[ext].push(file);
});

return groupedFiles;
} catch (error) {
console.error('Ошибка при группировке файлов:', error);
throw error;
}
}

groupFilesByType(path.join(__dirname, 'uploads'))
.then(groups => {
console.log('Файлы по типам:');
Object.entries(groups).forEach(([type, files]) => {
console.log(`${type} (${files.length}): ${files.join(', ')}`);
});
})
.catch(err => console.error('Ошибка:', err));

Для анализа и трансформации содержимого файлов можно комбинировать получение списка с чтением:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function findStringInFiles(directoryPath, searchString) {
try {
const files = await fs.readdir(directoryPath);
const textFiles = files.filter(file => 
['.txt', '.md', '.js', '.html', '.css'].includes(path.extname(file).toLowerCase())
);

const results = [];

for (const file of textFiles) {
const filePath = path.join(directoryPath, file);
const content = await fs.readFile(filePath, 'utf8');

if (content.includes(searchString)) {
results.push({
file,
path: filePath,
occurrences: (content.match(new RegExp(searchString, 'g')) || []).length
});
}
}

return results;
} catch (error) {
console.error('Ошибка при поиске в файлах:', error);
throw error;
}
}

// Поиск строки "TODO" во всех текстовых файлах
findStringInFiles(path.join(__dirname, 'project'), 'TODO')
.then(results => {
console.log(`Найдено ${results.length} файлов с "TODO":`);
results.forEach(result => {
console.log(`${result.file} – ${result.occurrences} вхождений`);
});
})
.catch(err => console.error('Ошибка:', err));

При обработке большого количества файлов стоит учитывать ограничения операционной системы и использовать потоковую обработку или разбивать операции на части:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function processBatchedFiles(directoryPath, batchSize = 10, processor) {
try {
const allFiles = await fs.readdir(directoryPath);
const results = [];

// Обработка файлов по частям
for (let i = 0; i < allFiles.length; i += batchSize) {
const batch = allFiles.slice(i, i + batchSize);

// Параллельная обработка файлов в пакете
const batchResults = await Promise.all(
batch.map(async file => {
const filePath = path.join(directoryPath, file);
return await processor(filePath, file);
})
);

results.push(...batchResults);

// Даем event loop "отдышаться" между пакетами
await new Promise(resolve => setTimeout(resolve, 0));
}

return results;
} catch (error) {
console.error('Ошибка при пакетной обработке:', error);
throw error;
}
}

// Пример функции-обработчика: получение размера файла
async function getFileSize(filePath, fileName) {
try {
const stats = await fs.stat(filePath);
return {
name: fileName,
size: stats.size
};
} catch (error) {
return {
name: fileName,
error: error.message
};
}
}

// Использование
processBatchedFiles(path.join(__dirname, 'large_directory'), 20, getFileSize)
.then(results => console.log(`Обработано ${results.length} файлов`))
.catch(err => console.error('Ошибка:', err));

Практические решения типичных задач с директориями

Теперь, когда мы рассмотрели основные методы получения и обработки файлов, давайте обратимся к практическим решениям для распространенных задач, возникающих при работе с директориями в Node.js проектах. 🛠️

Начнем с рекурсивного обхода директорий — одной из самых востребованных задач:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');

async function walkDirectory(dir, fileList = []) {
const files = await fs.readdir(dir);

for (const file of files) {
const filePath = path.join(dir, file);
const stat = await fs.stat(filePath);

if (stat.isDirectory()) {
// Рекурсивно обходим вложенную директорию
fileList = await walkDirectory(filePath, fileList);
} else {
// Добавляем файл в список
fileList.push(filePath);
}
}

return fileList;
}

// Пример использования
walkDirectory(path.join(__dirname, 'project'))
.then(files => {
console.log(`Найдено ${files.length} файлов:`);
files.forEach(file => console.log(file));
})
.catch(err => console.error('Ошибка при обходе директорий:', err));

Для создания и управления временными директориями — частая задача при работе с загрузкой файлов:

JS
Скопировать код
const fs = require('fs').promises;
const path = require('path');
const os = require('os');
const crypto = require('crypto');

async function createTempDirectory() {
// Создаем уникальное имя для временной директории
const tempDirName = crypto.randomBytes(8).toString('hex');
const tempPath = path.join(os.tmpdir(), tempDirName);

try {
await fs.mkdir(tempPath);
console.log(`Создана временная директория: ${tempPath}`);
return tempPath;
} catch (error) {
console.error('Ошибка при создании временной директории:', error);
throw error;
}
}

async function cleanupTempFiles(directory) {
try {
const files = await fs.readdir(directory);

// Удаляем все файлы в директории
for (const file of files) {
const filePath = path.join(directory, file);
await fs.unlink(filePath);
}

// Удаляем саму директорию
await fs.rmdir(directory);
console.log(`Временная директория очищена: ${directory}`);
} catch (error) {
console.error('Ошибка при очистке временных файлов:', error);
throw error;
}
}

// Пример использования
async function processTempFiles() {
let tempDir = null;
try {
// Создаем временную директорию
tempDir = await createTempDirectory();

// Создаем тестовый файл
const testFilePath = path.join(tempDir, 'test.txt');
await fs.writeFile(testFilePath, 'Тестовые данные');

// Обрабатываем файлы...
console.log('Обработка файлов завершена');
} finally {
// Очищаем временные файлы даже в случае ошибки
if (tempDir) {
await cleanupTempFiles(tempDir);
}
}
}

processTempFiles().catch(err => console.error('Ошибка:', err));

Для отслеживания изменений в директории — полезно при разработке приложений с горячей перезагрузкой:

JS
Скопировать код
const fs = require('fs');
const path = require('path');

function watchDirectory(directory, onChange) {
console.log(`Отслеживание изменений в директории: ${directory}`);

// Настраиваем отслеживание с параметрами
const watcher = fs.watch(directory, { recursive: true }, (eventType, filename) => {
if (filename) {
console.log(`Событие: ${eventType}, файл: ${filename}`);
onChange(eventType, filename, path.join(directory, filename));
}
});

// Обработка завершения отслеживания
watcher.on('error', error => {
console.error('Ошибка при отслеживании директории:', error);
});

return {
stop: () => {
watcher.close();
console.log('Отслеживание директории остановлено');
}
};
}

// Пример использования
const stopWatching = watchDirectory(path.join(__dirname, 'src'), (eventType, filename, fullPath) => {
if (path.extname(filename) === '.js') {
console.log(`Обнаружено изменение в JavaScript файле: ${filename}`);
// Выполняем нужные действия при изменении JS файлов
}
});

// Остановка отслеживания через 5 минут
setTimeout(() => {
stopWatching.stop();
}, 5 * 60 * 1000);

Для работы с большим количеством файлов, используя потоковую обработку:

JS
Скопировать код
const fs = require('fs');
const path = require('path');
const { Transform } = require('stream');

// Создаем поток для чтения директории
function createDirectoryStream(directory) {
const files = fs.readdirSync(directory);
let index = 0;

// Создаем поток чтения
const stream = new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
callback(null, chunk);
},
flush(callback) {
callback();
}
});

// Функция для отправки следующего файла в поток
function pushNext() {
if (index < files.length) {
const filename = files[index++];
const filePath = path.join(directory, filename);
stream.push({ filename, path: filePath });

// Планируем отправку следующего файла
setImmediate(pushNext);
} else {
// Все файлы отправлены, закрываем поток
stream.push(null);
}
}

// Запускаем отправку файлов
setImmediate(pushNext);

return stream;
}

// Пример использования
function processLargeDirectory(directory) {
let processedCount = 0;

createDirectoryStream(directory)
.on('data', fileInfo => {
processedCount++;
console.log(`Обработка файла: ${fileInfo.filename}`);
// Здесь можно выполнять любую обработку файла
})
.on('end', () => {
console.log(`Обработка завершена. Всего файлов: ${processedCount}`);
})
.on('error', err => {
console.error('Ошибка при обработке директории:', err);
});
}

processLargeDirectory(path.join(__dirname, 'large_directory'));

Для создания автоматического бэкапа директорий:

JS
Скопировать код
const fs = require('fs');
const path = require('path');
const archiver = require('archiver'); // Требуется установить: npm install archiver

function backupDirectory(sourceDir, backupPath) {
// Создаем файл для архива
const output = fs.createWriteStream(backupPath);
const archive = archiver('zip', {
zlib: { level: 9 } // Максимальная компрессия
});

// Обработка событий
output.on('close', () => {
const sizeInMB = (archive.pointer() / 1024 / 1024).toFixed(2);
console.log(`Бэкап завершен. Размер архива: ${sizeInMB} MB`);
});

archive.on('warning', err => {
if (err.code === 'ENOENT') {
console.warn('Предупреждение:', err);
} else {
throw err;
}
});

archive.on('error', err => {
throw err;
});

// Связываем архиватор с файлом вывода
archive.pipe(output);

// Добавляем директорию в архив
archive.directory(sourceDir, false);

// Завершаем архивацию
archive.finalize();
}

// Пример использования
function createDateBasedBackup(sourceDir, backupDir) {
const now = new Date();
const timestamp = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}-${now.getMinutes().toString().padStart(2, '0')}`;
const backupFileName = `backup_${timestamp}.zip`;
const backupPath = path.join(backupDir, backupFileName);

// Убеждаемся, что директория для бэкапов существует
if (!fs.existsSync(backupDir)) {
fs.mkdirSync(backupDir, { recursive: true });
}

backupDirectory(sourceDir, backupPath);
}

// Создаем бэкап каталога проекта
createDateBasedBackup(
path.join(__dirname, 'project'),
path.join(__dirname, 'backups')
);

Ключевые моменты, которые стоит учитывать при работе с директориями в Node.js:

  • Производительность — для больших директорий всегда используйте асинхронные методы и избегайте блокировки event loop
  • Обработка ошибок — файловая система непредсказуема, всегда имейте план действий при возникновении ошибок
  • Кросс-платформенность — используйте модуль path для обеспечения совместимости между разными ОС
  • Ограничения ОС — учитывайте лимиты на количество одновременно открытых файлов и используйте потоковую обработку или пакетные методы
  • Тестирование — создавайте тесты, которые эмулируют файловую систему (например, с помощью mock-fs), чтобы избежать проблем в production

Мы рассмотрели основные методы получения списка файлов в директориях с использованием Node.js — от базовых синхронных операций до продвинутых асинхронных подходов с промисами. Помните: выбор правильного метода зависит от конкретной задачи. Для небольших утилит подойдет fs.readdirSync, для высоконагруженных приложений — fs.promises.readdir с async/await. При обработке больших директорий не забывайте о потоковой обработке и пакетных операциях. Эффективная работа с файловой системой — один из ключевых навыков, отличающих профессионального Node.js-разработчика.

Загрузка...