Работа с файловой системой в Node.js: полное руководство

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

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

Начать курс

Работа с файловой системой в Node.js: полное руководство

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

Подключение модуля fs и основные принципы

Для начала работы с файловой системой в Node.js необходимо подключить встроенный модуль fs. Это делается одной строкой кода:

const fs = require('fs');

Модуль fs предоставляет как синхронные, так и асинхронные методы. Асинхронные методы, как правило, принимают callback-функцию в качестве последнего аргумента и являются предпочтительными для production-кода, так как не блокируют event loop. Синхронные методы оканчиваются на Sync и могут быть полезны при инициализации приложения или в скриптах.

Кроме того, начиная с Node.js 10, доступна работа с fs/promises — версия методов, возвращающих промисы:

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

В этой статье мы будем использовать преимущественно асинхронный подход с промисами, так как он наиболее современный и удобный.

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

Чтение файлов — одна из самых частых операций. Рассмотрим три основных способа.

Чтение всего файла целиком (асинхронно)

Метод fs.readFile() читает содержимое файла полностью в память. Это удобно для небольших файлов.

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

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

readFileExample();

Чтение файла построчно (потоковое чтение)

Для больших файлов лучше использовать потоки (streams) или читать файл построчно с помощью readline:

const fs = require('fs');
const readline = require('readline');

async function readFileLineByLine() {
  const fileStream = fs.createReadStream('large-file.txt');
  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });

  for await (const line of rl) {
    console.log('Строка:', line);
  }
}

readFileLineByLine();

Синхронное чтение

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

const fs = require('fs');

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

Запись и обновление файлов

Node.js предоставляет несколько методов для записи данных в файлы.

Запись в файл (перезапись)

Метод fs.writeFile() создает новый файл или перезаписывает существующий:

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

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

writeFileExample();

Добавление данных в конец файла

Если нужно добавить данные, не удаляя существующие, используйте fs.appendFile():

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

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

appendToFile();

Работа с потоками для больших данных

Для записи больших объемов данных используйте fs.createWriteStream():

const fs = require('fs');

const writeStream = fs.createWriteStream('big-file.txt');
for (let i = 0; i < 1000000; i++) {
  writeStream.write(`Строка номер ${i}\n`);
}
writeStream.end();

Управление директориями и файлами

Помимо чтения и записи, часто требуется создавать, удалять и перемещать файлы и папки.

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

Метод fs.mkdir() создает новую папку. Опция recursive: true позволяет создавать вложенные директории:

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

async function createDirectories() {
  try {
    await fs.mkdir('project/src/components', { recursive: true });
    console.log('Директории созданы');
  } catch (err) {
    console.error('Ошибка:', err);
  }
}

createDirectories();

Удаление файлов и папок

Для удаления файла используйте fs.unlink(), для пустой директории — fs.rmdir(). Для удаления папки со всем содержимым — fs.rm() с опцией recursive: true:

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

async function deleteExample() {
  try {
    await fs.unlink('temp-file.txt');
    console.log('Файл удален');
    
    // Удаление папки со всем содержимым
    await fs.rm('temp-folder', { recursive: true, force: true });
    console.log('Папка удалена');
  } catch (err) {
    console.error('Ошибка удаления:', err);
  }
}

deleteExample();

Переименование и перемещение

Метод fs.rename() позволяет переименовать или переместить файл/папку:

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

async function moveFile() {
  try {
    await fs.rename('source.txt', 'backup/source.txt');
    console.log('Файл перемещен');
  } catch (err) {
    console.error('Ошибка:', err);
  }
}

moveFile();

Работа с путями с помощью модуля path

Модуль path — незаменимый помощник

Блоги

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