Работа с файловой системой в JavaScript (Node.js): полное руководство для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с файловой системой в JavaScript (Node.js): полное руководство для начинающих

Работа с файловой системой — одна из ключевых задач при создании серверных приложений, скриптов автоматизации или утилит для обработки данных. В JavaScript (Node.js) для этого существует встроенный модуль fs (File System). Эта статья познакомит вас с основами работы с файлами и папками в Node.js, покажет, как читать, записывать, создавать и удалять файлы, а также объяснит разницу между синхронными и асинхронными методами.

Что такое модуль fs в Node.js?

Модуль fs предоставляет API для взаимодействия с файловой системой операционной системы. Он позволяет выполнять такие операции, как:

  • Чтение содержимого файлов
  • Запись данных в файлы
  • Создание и удаление директорий
  • Переименование и копирование файлов
  • Проверка существования файлов
  • Получение информации о файлах (статистика)

Чтобы начать использовать модуль fs, его нужно подключить в вашем коде:

const fs = require('fs');

Все методы модуля fs доступны в трех вариантах: синхронном (с суффиксом Sync), асинхронном с колбэками и асинхронном на основе промисов (с использованием fs.promises). В этом руководстве мы сосредоточимся на современном подходе с использованием async/await.

Чтение файлов в Node.js

Самый простой способ прочитать содержимое файла — использовать метод readFile из fs.promises. Рассмотрим пример:

const fs = require('fs').promises;

async function readFileExample() {
    try {
        const data = await fs.readFile('example.txt', 'utf8');
        console.log('Содержимое файла:', data);
    } catch (error) {
        console.error('Ошибка при чтении файла:', error.message);
    }
}

readFileExample();

В этом примере:

  • Мы импортируем fs.promises — версию модуля, которая возвращает промисы.
  • Функция readFile принимает путь к файлу и кодировку (в данном случае 'utf8').
  • Если файл не существует, будет выброшена ошибка, которую мы обрабатываем в блоке catch.

Если вам нужно прочитать файл синхронно (в простых скриптах), используйте readFileSync:

const fs = require('fs');

try {
    const data = fs.readFileSync('example.txt', 'utf8');
    console.log(data);
} catch (error) {
    console.error(error.message);
}

Важно: Синхронные методы блокируют выполнение кода до завершения операции. В серверных приложениях (например, на Express) всегда используйте асинхронные методы, чтобы не блокировать обработку других запросов.

Запись данных в файлы

Для записи данных в файл используется метод writeFile. Если файл существует, его содержимое будет перезаписано. Если файла нет — он будет создан автоматически.

const fs = require('fs').promises;

async function writeFileExample() {
    try {
        const content = 'Привет, мир! Это тестовая запись.';
        await fs.writeFile('output.txt', content, 'utf8');
        console.log('Файл успешно записан!');
    } catch (error) {
        console.error('Ошибка записи:', error.message);
    }
}

writeFileExample();

Если вы хотите добавить данные в конец существующего файла (не перезаписывая его), используйте флаг appendFile:

const fs = require('fs').promises;

async function appendToFile() {
    try {
        await fs.appendFile('log.txt', `Новая запись: ${new Date()}\n`, 'utf8');
        console.log('Данные добавлены в конец файла');
    } catch (error) {
        console.error('Ошибка:', error.message);
    }
}

appendToFile();

Создание и удаление директорий

Работа с папками так же важна, как и работа с файлами. Рассмотрим основные операции:

Создание папки

const fs = require('fs').promises;

async function createDirectory() {
    try {
        await fs.mkdir('new_folder');
        console.log('Папка создана');
    } catch (error) {
        if (error.code === 'EEXIST') {
            console.log('Папка уже существует');
        } else {
            console.error('Ошибка:', error.message);
        }
    }
}

createDirectory();

Чтобы создать вложенные папки (например, parent/child/grandchild), добавьте опцию { recursive: true }:

await fs.mkdir('parent/child/grandchild', { recursive: true });

Удаление папки

Удалить пустую папку можно с помощью rmdir. Для удаления папки со всем содержимым используйте rm с опцией { recursive: true } (доступно с Node.js 14.14):

const fs = require('fs').promises;

async function deleteDirectory() {
    try {
        await fs.rm('old_folder', { recursive: true, force: true });
        console.log('Папка удалена');
    } catch (error) {
        console.error('Ошибка:', error.message);
    }
}

deleteDirectory();

Проверка существования и получение информации о файлах

Перед выполнением операций с файлами часто нужно проверить их существование или получить информацию (размер, дату создания и т.д.):

const fs = require('fs').promises;

async function checkFile() {
    try {
        const stats = await fs.stat('example.txt');
        console.log('Файл существует');
        console.log('Размер:', stats.size, 'байт');
        console.log('Создан:', stats.birthtime);
        console.log('Это файл?', stats.isFile());
        console.log('Это папка?', stats.isDirectory());
    } catch (error) {
        if (error.code === 'ENOENT') {
            console.log('Файл не найден');
        } else {
            console.error('Ошибка:', error.message);
        }
    }
}

checkFile();

Метод stat возвращает объект Stats, который содержит подробную информацию о файле или директории.

Практический пример: логгер событий

Блоги

Рекомендаций по книгам