Перейти к содержанию

Файловая система

latest

Стабильность: 2 – Стабильная

АПИ является удовлетворительным. Совместимость с NPM имеет высший приоритет и не будет нарушена кроме случаев явной необходимости.

Модуль node:fs позволяет взаимодействовать с файловой системой по образцу стандартных функций POSIX.

Чтобы использовать API на основе промисов:

1
import * as fs from 'node:fs/promises';
1
const fs = require('node:fs/promises');

Чтобы использовать API с обратным вызовом и синхронные API:

1
import * as fs from 'node:fs';
1
const fs = require('node:fs');

Все операции с файловой системой доступны в синхронной форме, с обратным вызовом и в виде промисов, и их можно вызывать как из CommonJS, так и из модулей ES (ESM).

Пример с промисами

Операции на промисах возвращают промис, который выполняется, когда асинхронная операция завершена.

1
2
3
4
5
6
7
8
import { unlink } from 'node:fs/promises';

try {
  await unlink('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (error) {
  console.error('there was an error:', error.message);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const { unlink } = require('node:fs/promises');

(async function(path) {
  try {
    await unlink(path);
    console.log(`successfully deleted ${path}`);
  } catch (error) {
    console.error('there was an error:', error.message);
  }
})('/tmp/hello');

Пример с обратным вызовом

В форме с обратным вызовом последним аргументом передаётся функция завершения; операция выполняется асинхронно. Набор аргументов, передаваемых в эту функцию, зависит от метода, но первый аргумент всегда зарезервирован под исключение. Если операция завершилась успешно, первым аргументом будет null или undefined.

1
2
3
4
5
6
import { unlink } from 'node:fs';

unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});
1
2
3
4
5
6
const { unlink } = require('node:fs');

unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

Варианты API модуля node:fs с обратным вызовом предпочтительнее промисов, когда нужна максимальная производительность (и по времени выполнения, и по выделению памяти).

Синхронный пример

Синхронные API блокируют цикл событий Node.js и дальнейшее выполнение JavaScript до завершения операции. Исключения выбрасываются сразу; их можно обработать в try…catch или позволить всплыть.

1
2
3
4
5
6
7
8
import { unlinkSync } from 'node:fs';

try {
  unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}
1
2
3
4
5
6
7
8
const { unlinkSync } = require('node:fs');

try {
  unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}

API промисов (fs/promises)

API fs/promises предоставляет асинхронные методы файловой системы, возвращающие промисы.

Эти API используют встроенный пул потоков Node.js для выполнения операций с файловой системой вне потока цикла событий. Они не синхронизированы и не рассчитаны на многопоточную безопасность. При нескольких одновременных изменениях одного и того же файла возможна порча данных — действуйте осторожно.

Класс: FileHandle

Объект FileHandle — обёртка над числовым дескриптором файла.

Экземпляры FileHandle создаются методом fsPromises.open().

Все объекты FileHandle являются EventEmitter.

Если FileHandle не закрыть через filehandle.close(), среда попытается автоматически закрыть дескриптор и выдать предупреждение процессу, чтобы уменьшить риск утечек памяти. На такое поведение полагаться не следует: оно может сработать ненадёжно, и файл может остаться открытым. Всегда явно закрывайте FileHandle. В будущем Node.js может изменить эту логику.

Событие: 'close'

Событие 'close' генерируется, когда FileHandle закрыт и больше использоваться не может.

filehandle.appendFile(data[, options])

Псевдоним filehandle.writeFile().

При работе с дескриптором файла режим нельзя изменить относительно того, что был задан при fsPromises.open(). Поэтому метод эквивалентен filehandle.writeFile().

filehandle.chmod(mode)

  • mode <integer> битовая маска режима файла.
  • Возвращает: <Promise> при успехе выполняется с undefined.

Изменяет права доступа к файлу. См. chmod(2).

filehandle.chown(uid, gid)

  • uid <integer> идентификатор пользователя — нового владельца файла.
  • gid <integer> идентификатор группы — новой группы файла.
  • Возвращает: <Promise> при успехе выполняется с undefined.

Меняет владельца файла. Обёртка над chown(2).

filehandle.close()

  • Возвращает: <Promise> при успехе выполняется с undefined.

Закрывает дескриптор после завершения всех отложенных операций над ним.

1
2
3
4
5
6
7
8
import { open } from 'node:fs/promises';

let filehandle;
try {
  filehandle = await open('thefile.txt', 'r');
} finally {
  await filehandle?.close();
}

filehandle.createReadStream([options])

В options можно задать start и end, чтобы прочитать диапазон байт вместо всего файла. Оба значения включаются в диапазон, отсчёт с 0; допустимый диапазон — [0, Number.MAX_SAFE_INTEGER]. Если start опущен или undefined, filehandle.createReadStream() читает последовательно с текущей позиции в файле. Для encoding допустимы те же значения, что принимает Buffer.

Если FileHandle указывает на символьное устройство с только блокирующим чтением (например клавиатуру или звуковую карту), чтение не завершится, пока не появятся данные. Из-за этого процесс может не завершиться, а поток — не закрыться естественным образом.

По умолчанию поток сгенерирует событие 'close' после уничтожения. Чтобы изменить поведение, установите emitClose в false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { open } from 'node:fs/promises';

const fd = await open('/dev/input/event0');
// Create a stream from some character device.
const stream = fd.createReadStream();
setTimeout(() => {
  stream.close(); // This may not close the stream.
  // Artificially marking end-of-stream, as if the underlying resource had
  // indicated end-of-file by itself, allows the stream to close.
  // This does not cancel pending read operations, and if there is such an
  // operation, the process may still not be able to exit successfully
  // until it finishes.
  stream.push(null);
  stream.read(0);
}, 100);

Если autoClose равен false, дескриптор файла не закрывается даже при ошибке. Закрыть его и убедиться в отсутствии утечки дескрипторов — ответственность приложения. Если autoClose равен true (по умолчанию), при 'error' или 'end' дескриптор закрывается автоматически.

Пример: прочитать последние 10 байт файла длиной 100 байт:

1
2
3
4
import { open } from 'node:fs/promises';

const fd = await open('sample.txt');
fd.createReadStream({ start: 90, end: 99 });

filehandle.createWriteStream([options])

  • options <Object>
    • encoding <string> По умолчанию: 'utf8'
    • autoClose <boolean> По умолчанию: true
    • emitClose <boolean> По умолчанию: true
    • start <integer>
    • highWaterMark <number> По умолчанию: 16384
    • flush <boolean> при true базовый дескриптор файла сбрасывается на носитель перед закрытием. По умолчанию: false.
  • Возвращает: <fs.WriteStream>

В options также может быть указан start для записи с позиции после начала файла; допустимые значения в диапазоне [0, Number.MAX_SAFE_INTEGER]. Чтобы изменять файл, а не заменять его целиком, для open может понадобиться флаг r+ вместо r по умолчанию. Для encoding допустимы те же значения, что принимает Buffer.

Если autoClose равен true (по умолчанию), при 'error' или 'finish' дескриптор закрывается автоматически. Если autoClose равен false, дескриптор не закрывается даже при ошибке. Закрыть его и избежать утечки дескрипторов — задача приложения.

По умолчанию поток сгенерирует событие 'close' после уничтожения. Чтобы изменить поведение, установите emitClose в false.

filehandle.datasync()

  • Возвращает: <Promise> при успехе выполняется с undefined.

Переводит все отложенные операции ввода-вывода для этого файла в состояние завершённой синхронизированной записи ОС. Подробности см. в документации POSIX fdatasync(2).

В отличие от filehandle.sync, этот метод не сбрасывает изменённые метаданные.

filehandle.fd

  • Тип: <number> числовой дескриптор файла, которым управляет объект FileHandle.

filehandle.pull([...transforms][, options])

Стабильность: 1 – Экспериментальная

Фича изменяется и не допускается флагом командной строки. Может быть изменена или удалена в последующих версиях.

  • ...transforms <Function> | <Object> необязательные преобразования через stream/iter pull().
  • options <Object>
    • signal <AbortSignal>
    • autoClose <boolean> закрыть дескриптор файла по окончании потока. По умолчанию: false.
    • start <number> смещение в байтах, с которого начинать чтение. Если задано, используется явное позиционирование (семантика pread). По умолчанию: текущая позиция в файле.
    • limit <number> максимум байт для чтения до завершения итератора. Чтение останавливается, когда передано limit байт или достигнут конец файла — в зависимости от того, что наступит раньше. По умолчанию: до конца файла.
    • chunkSize <number> размер буфера в байтах для каждой операции чтения. По умолчанию: 131072 (128 КиБ).
  • Возвращает: <AsyncIterable<Uint8Array[]>>

Возвращает содержимое файла как асинхронный итерируемый объект по модели pull из node:stream/iter. Чтение идёт блоками по chunkSize байт (по умолчанию 128 КиБ). Если заданы преобразования, они применяются через stream/iter pull().

Пока итерируемый объект потребляется, дескриптор файла заблокирован; разблокировка — по завершении итерации, при ошибке или при прерывании потребителем.

Функция доступна только при включённом флаге --experimental-stream-iter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { open } from 'node:fs/promises';
import { text } from 'node:stream/iter';
import { compressGzip } from 'node:zlib/iter';

const fh = await open('input.txt', 'r');

// Read as text
console.log(await text(fh.pull({ autoClose: true })));

// Read 1 KB starting at byte 100
const fh2 = await open('input.txt', 'r');
console.log(await text(fh2.pull({ start: 100, limit: 1024, autoClose: true })));

// Read with compression
const fh3 = await open('input.txt', 'r');
const compressed = fh3.pull(compressGzip(), { autoClose: true });
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const { open } = require('node:fs/promises');
const { text } = require('node:stream/iter');
const { compressGzip } = require('node:zlib/iter');

async function run() {
  const fh = await open('input.txt', 'r');

  // Read as text
  console.log(await text(fh.pull({ autoClose: true })));

  // Read 1 KB starting at byte 100
  const fh2 = await open('input.txt', 'r');
  console.log(await text(fh2.pull({ start: 100, limit: 1024, autoClose: true })));

  // Read with compression
  const fh3 = await open('input.txt', 'r');
  const compressed = fh3.pull(compressGzip(), { autoClose: true });
}

run().catch(console.error);

filehandle.pullSync([...transforms][, options])

Стабильность: 1 – Экспериментальная

Фича изменяется и не допускается флагом командной строки. Может быть изменена или удалена в последующих версиях.

  • ...transforms <Function> | <Object> необязательные преобразования через stream/iter pullSync().
  • options <Object>
    • autoClose <boolean> закрыть дескриптор файла по окончании потока. По умолчанию: false.
    • start <number> смещение в байтах для начала чтения. Если задано, используется явное позиционирование. По умолчанию: текущая позиция в файле.
    • limit <number> максимум байт до завершения итератора. По умолчанию: до конца файла.
    • chunkSize <number> размер буфера в байтах для каждой операции чтения. По умолчанию: 131072 (128 КиБ).
  • Возвращает: <Iterable<Uint8Array[]>>

Синхронный аналог filehandle.pull(). Возвращает синхронный итерируемый объект, который читает файл синхронным вводом-выводом в основном потоке. Чтение идёт блоками по chunkSize байт (по умолчанию 128 КиБ).

Пока итерируемый объект потребляется, дескриптор файла заблокирован. В отличие от асинхронного pull(), AbortSignal не поддерживается — все операции синхронны.

Функция доступна только при включённом флаге --experimental-stream-iter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { open } from 'node:fs/promises';
import { textSync, pipeToSync } from 'node:stream/iter';
import { compressGzipSync, decompressGzipSync } from 'node:zlib/iter';

const fh = await open('input.txt', 'r');

// Read as text (sync)
console.log(textSync(fh.pullSync({ autoClose: true })));

// Sync compress pipeline: file -> gzip -> file
const src = await open('input.txt', 'r');
const dst = await open('output.gz', 'w');
pipeToSync(src.pullSync(compressGzipSync(), { autoClose: true }), dst.writer({ autoClose: true }));
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const { open } = require('node:fs/promises');
const { textSync, pipeToSync } = require('node:stream/iter');
const { compressGzipSync, decompressGzipSync } = require('node:zlib/iter');

async function run() {
  const fh = await open('input.txt', 'r');

  // Read as text (sync)
  console.log(textSync(fh.pullSync({ autoClose: true })));

  // Sync compress pipeline: file -> gzip -> file
  const src = await open('input.txt', 'r');
  const dst = await open('output.gz', 'w');
  pipeToSync(
    src.pullSync(compressGzipSync(), { autoClose: true }),
    dst.writer({ autoClose: true }),
  );
}

run().catch(console.error);

filehandle.read(buffer, offset, length, position)

  • buffer <Buffer> | <TypedArray> | <DataView> Буфер, в который будут помещены считанные из файла данные.
  • offset <integer> Позиция в буфере, начиная с которой нужно заполнять данные. По умолчанию: 0
  • length <integer> Количество байт для чтения. По умолчанию: buffer.byteLength - offset
  • position <integer> | <bigint> | null Позиция в файле, с которой следует начать чтение данных. Если null или -1, данные читаются из текущей позиции файла, и эта позиция будет обновлена. Если position является неотрицательным целым числом, текущая позиция файла останется неизменной. По умолчанию: null
  • Возвращает: <Promise> При успешном выполнении исполняется объектом с двумя свойствами:

Читает данные из файла и помещает их в переданный буфер.

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

filehandle.read([options])

  • options <Object>
    • buffer <Buffer> | <TypedArray> | <DataView> Буфер, в который будут помещены считанные из файла данные. По умолчанию: Buffer.alloc(16384)
    • offset <integer> Позиция в буфере, начиная с которой нужно заполнять данные. По умолчанию: 0
    • length <integer> Количество байт для чтения. По умолчанию: buffer.byteLength - offset
    • position <integer> | <bigint> | null Позиция в файле, с которой следует начать чтение данных. Если null или -1, данные читаются из текущей позиции файла, и эта позиция будет обновлена. Если position является неотрицательным целым числом, текущая позиция файла останется неизменной. По умолчанию: null
  • Возвращает: <Promise> При успешном выполнении исполняется объектом с двумя свойствами:

Читает данные из файла и помещает их в переданный буфер.

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

filehandle.read(buffer[, options])

  • buffer <Buffer> | <TypedArray> | <DataView> Буфер, в который будут помещены считанные из файла данные.
  • options <Object>
    • offset <integer> Позиция в буфере, начиная с которой нужно заполнять данные. По умолчанию: 0
    • length <integer> Количество байт для чтения. По умолчанию: buffer.byteLength - offset
    • position <integer> | <bigint> | null Позиция в файле, с которой следует начать чтение данных. Если null или -1, данные читаются из текущей позиции файла, и эта позиция будет обновлена. Если position является неотрицательным целым числом, текущая позиция файла останется неизменной. По умолчанию: null
  • Возвращает: <Promise> При успешном выполнении исполняется объектом с двумя свойствами:

Читает данные из файла и помещает их в переданный буфер.

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

filehandle.readableWebStream([options])

Возвращает байтовый ReadableStream для чтения содержимого файла.

Будет выброшена ошибка, если метод вызван более одного раза или после закрытия либо в процессе закрытия FileHandle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import {
  open,
} from 'node:fs/promises';

const file = await open('./some/file/to/read');

for await (const chunk of file.readableWebStream())
  console.log(chunk);

await file.close();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const {
  open,
} = require('node:fs/promises');

(async () => {
  const file = await open('./some/file/to/read');

  for await (const chunk of file.readableWebStream())
    console.log(chunk);

  await file.close();
})();

Хотя ReadableStream прочитает файл до конца, он не закроет FileHandle автоматически. Пользовательский код всё равно должен вызвать метод fileHandle.close(), если только опция autoClose не установлена в true.

filehandle.readFile(options)

  • options <Object> | <string>
    • encoding <string> | null По умолчанию: null
    • signal <AbortSignal> позволяет прервать выполняющийся readFile
  • Возвращает: <Promise> При успешном выполнении исполняется содержимым файла. Если кодировка не указана (через options.encoding), данные возвращаются как объект Buffer. В противном случае это будет строка.

Асинхронно читает всё содержимое файла.

Если options — строка, она задаёт encoding.

FileHandle должен поддерживать чтение.

Если для файлового дескриптора был выполнен один или несколько вызовов filehandle.read(), а затем вызывается filehandle.readFile(), данные будут прочитаны от текущей позиции до конца файла. Чтение не всегда начинается с начала файла.

filehandle.readLines([options])

Вспомогательный метод для создания интерфейса readline и потокового чтения файла. Описание параметров см. в filehandle.createReadStream().

1
2
3
4
5
6
7
import { open } from 'node:fs/promises';

const file = await open('./some/file/to/read');

for await (const line of file.readLines()) {
  console.log(line);
}
1
2
3
4
5
6
7
8
9
const { open } = require('node:fs/promises');

(async () => {
  const file = await open('./some/file/to/read');

  for await (const line of file.readLines()) {
    console.log(line);
  }
})();

filehandle.readv(buffers[, position])

  • buffers <Buffer[]> | <TypedArray[]> | <DataView[]>
  • position <integer> | null Смещение от начала файла, с которого нужно читать данные. Если position не является number, данные будут читаться из текущей позиции. По умолчанию: null
  • Возвращает: <Promise> При успешном выполнении исполняется объектом с двумя свойствами:

Читает данные из файла и записывает их в массив объектов ArrayBufferView.

filehandle.stat([options])

  • options <Object>
    • bigint <boolean> Должны ли числовые значения в возвращаемом объекте fs.Stats быть bigint. По умолчанию: false.
    • signal <AbortSignal> AbortSignal для отмены операции. По умолчанию: undefined.
  • Возвращает: <Promise> При успешном выполнении исполняется объектом fs.Stats для файла.

filehandle.sync()

  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Запрашивает сброс всех данных для открытого файлового дескриптора на устройство хранения. Конкретная реализация зависит от операционной системы и устройства. Подробнее см. документацию POSIX для fsync(2).

filehandle.truncate(len)

  • len <integer> По умолчанию: 0
  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Усекает файл.

Если файл был больше len байт, в нём будут сохранены только первые len байт.

Следующий пример сохраняет только первые четыре байта файла:

1
2
3
4
5
6
7
8
9
import { open } from 'node:fs/promises';

let filehandle = null;
try {
  filehandle = await open('temp.txt', 'r+');
  await filehandle.truncate(4);
} finally {
  await filehandle?.close();
}

Если ранее файл был короче len байт, он будет расширен, а добавленная часть будет заполнена нулевыми байтами ('\0'):

Если len отрицателен, будет использовано значение 0.

filehandle.utimes(atime, mtime)

Изменяет временные метки файловой системы для объекта, на который ссылается FileHandle, и при успешном выполнении исполняет промис без аргументов.

filehandle.write(buffer, offset[, length[, position]])

  • buffer <Buffer> | <TypedArray> | <DataView>
  • offset <integer> Начальная позиция внутри buffer, откуда начинаются данные для записи.
  • length <integer> Количество байт из buffer, которые нужно записать. По умолчанию: buffer.byteLength - offset
  • position <integer> | null Смещение от начала файла, куда должны быть записаны данные из buffer. Если position не является number, данные будут записаны в текущую позицию. Подробнее см. POSIX pwrite(2). По умолчанию: null
  • Возвращает: <Promise>

Записывает buffer в файл.

Промис выполняется объектом с двумя свойствами:

Небезопасно вызывать filehandle.write() несколько раз для одного и того же файла, не дожидаясь выполнения (или отклонения) промиса. Для такого сценария используйте filehandle.createWriteStream().

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

filehandle.write(buffer[, options])

Записывает buffer в файл.

Подобно описанной выше функции filehandle.write, эта версия принимает необязательный объект options. Если объект options не указан, используются приведённые выше значения по умолчанию.

filehandle.write(string[, position[, encoding]])

  • string <string>
  • position <integer> | null Смещение от начала файла, куда должны быть записаны данные из string. Если position не является number, данные будут записаны в текущую позицию. Подробнее см. POSIX pwrite(2). По умолчанию: null
  • encoding <string> Ожидаемая кодировка строки. По умолчанию: 'utf8'
  • Возвращает: <Promise>

Записывает string в файл. Если string не является строкой, промис будет отклонён с ошибкой.

Промис выполняется объектом с двумя свойствами:

  • bytesWritten <integer> Количество записанных байт
  • buffer <string> Ссылка на записанную string.

Небезопасно вызывать filehandle.write() несколько раз для одного и того же файла, не дожидаясь выполнения (или отклонения) промиса. Для такого сценария используйте filehandle.createWriteStream().

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

filehandle.writeFile(data, options)

Асинхронно записывает данные в файл, заменяя файл, если он уже существует. data может быть строкой, буфером, объектом AsyncIterable или Iterable. При успехе промис выполняется без аргументов.

Если options — строка, она задаёт encoding.

FileHandle должен поддерживать запись.

Небезопасно вызывать filehandle.writeFile() несколько раз для одного и того же файла, не дожидаясь выполнения (или отклонения) промиса.

Если для файлового дескриптора был выполнен один или несколько вызовов filehandle.write(), а затем вызывается filehandle.writeFile(), данные будут записаны от текущей позиции до конца файла. Запись не всегда начинается с начала файла.

filehandle.writev(buffers[, position])

  • buffers <Buffer[]> | <TypedArray[]> | <DataView[]>
  • position <integer> | null Смещение от начала файла, куда должны быть записаны данные из buffers. Если position не является number, данные будут записаны в текущую позицию. По умолчанию: null
  • Возвращает: <Promise>

Записывает массив объектов ArrayBufferView в файл.

Промис выполняется объектом с двумя свойствами:

Небезопасно вызывать writev() несколько раз для одного и того же файла, не дожидаясь выполнения (или отклонения) промиса.

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

filehandle.writer([options])

Стабильность: 1 - Экспериментальная

  • options <Object>
    • autoClose <boolean> Закрывать файловый дескриптор, когда writer завершает работу или переходит в состояние ошибки. По умолчанию: false.
    • start <number> Смещение в байтах, с которого нужно начинать запись. Если указано, запись использует явное позиционирование. По умолчанию: текущая позиция файла.
    • limit <number> Максимальное число байт, которое writer примет. Асинхронные записи (write(), writev()), превышающие лимит, отклоняются с ERR_OUT_OF_RANGE. Синхронные записи (writeSync(), writevSync()) возвращают false. По умолчанию: без ограничений.
    • chunkSize <number> Максимальный размер чанка в байтах для синхронных операций записи. Записи больше этого порога переводятся на асинхронный ввод-вывод. Для оптимальной производительности pipeTo() установите значение, совпадающее с chunkSize у reader. По умолчанию: 131072 (128 KB).
  • Возвращает: <Object>
    • write(chunk[, options]) <Function> Возвращает <Promise<void>>. Принимает Uint8Array, Buffer или строку (в кодировке UTF-8).
    • writev(chunks[, options]) <Function> Возвращает <Promise<void>>. Использует scatter/gather I/O через один системный вызов writev(). Принимает массивы с элементами смешанных типов Uint8Array/string.
    • writeSync(chunk) <Function> Возвращает boolean. Пытается выполнить синхронную запись. Возвращает true, если запись успешна, и false, если вызывающему коду следует перейти на асинхронный write(). false возвращается, когда writer закрыт/в состоянии ошибки, когда асинхронная операция уже выполняется, когда размер чанка превышает chunkSize или когда запись превысила бы limit.
    • writevSync(chunks) <Function> Возвращает boolean. Синхронная пакетная запись. Семантика переключения на запасной вариант такая же, как у writeSync().
    • end([options]) <Function> Возвращает <Promise<number>> с общим числом записанных байт. Идемпотентен: возвращает totalBytesWritten, если уже закрыт, и возвращает ожидающий промис, если уже находится в процессе закрытия. Отклоняется, если writer находится в состоянии ошибки.
      • options <Object>
        • signal <AbortSignal> Если сигнал уже прерван, end() отклоняется с AbortError, а writer остаётся открытым.
    • endSync() <Function> Возвращает number | number: общее число записанных байт при успехе или -1, если writer находится в состоянии ошибки либо выполняется асинхронная операция. Идемпотентен, если уже закрыт.
    • fail(reason) <Function> Переводит writer в конечное состояние ошибки. Синхронный метод. Если writer уже закрыт или находится в состоянии ошибки, ничего не делает. Если autoClose равно true, синхронно закрывает файловый дескриптор.

Возвращает writer из node:stream/iter, работающий поверх данного файлового дескриптора.

Writer поддерживает как Symbol.asyncDispose, так и Symbol.dispose:

  • await using w = fh.writer() — if the writer is still open (no end() called), asyncDispose calls fail(). If end() is pending, it waits for it to complete.
  • using w = fh.writer() — calls fail() unconditionally.

Методы writeSync() и writevSync() включают быстрый try-sync путь, используемый stream/iter pipeTo(). Когда размер чанка reader совпадает с chunkSize у writer, все записи в конвейере pipeTo() завершаются синхронно без накладных расходов на промисы.

Эта функция доступна только при включённом флаге --experimental-stream-iter.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { open } from 'node:fs/promises';
import { from, pipeTo } from 'node:stream/iter';
import { compressGzip } from 'node:zlib/iter';

// Async pipeline
const fh = await open('output.gz', 'w');
await pipeTo(from('Hello!'), compressGzip(), fh.writer({ autoClose: true }));

// Sync pipeline with limit
const src = await open('input.txt', 'r');
const dst = await open('output.txt', 'w');
const w = dst.writer({ limit: 1024 * 1024 }); // Max 1 MB
await pipeTo(src.pull({ autoClose: true }), w);
await w.end();
await dst.close();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
const { open } = require('node:fs/promises');
const { from, pipeTo } = require('node:stream/iter');
const { compressGzip } = require('node:zlib/iter');

async function run() {
  // Async pipeline
  const fh = await open('output.gz', 'w');
  await pipeTo(from('Hello!'), compressGzip(), fh.writer({ autoClose: true }));

  // Sync pipeline with limit
  const src = await open('input.txt', 'r');
  const dst = await open('output.txt', 'w');
  const w = dst.writer({ limit: 1024 * 1024 }); // Max 1 MB
  await pipeTo(src.pull({ autoClose: true }), w);
  await w.end();
  await dst.close();
}

run().catch(console.error);

filehandle[Symbol.asyncDispose]()

Вызывает filehandle.close() и возвращает промис, который исполняется, когда filehandle закрыт.

fsPromises.access(path[, mode])

  • path <string> | <Buffer> | <URL>
  • mode <integer> По умолчанию: fs.constants.F_OK
  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Проверяет права пользователя на файл или каталог, указанный в path. Аргумент mode — необязательное целое число, задающее проверки доступности, которые нужно выполнить. mode должен быть либо значением fs.constants.F_OK, либо маской, составленной побитовым ИЛИ из fs.constants.R_OK, fs.constants.W_OK и fs.constants.X_OK (например, fs.constants.W_OK | fs.constants.R_OK). Возможные значения mode см. в константах доступа к файлам.

Если проверка доступности успешна, промис выполняется без значения. Если какая-либо из проверок завершится неудачей, промис будет отклонён объектом Error. Следующий пример проверяет, может ли текущий процесс читать и записывать файл /etc/passwd.

1
2
3
4
5
6
7
8
import { access, constants } from 'node:fs/promises';

try {
  await access('/etc/passwd', constants.R_OK | constants.W_OK);
  console.log('can access');
} catch {
  console.error('cannot access');
}

Не рекомендуется использовать fsPromises.access() для проверки доступности файла перед вызовом fsPromises.open(). Это создаёт состояние гонки, поскольку между двумя вызовами другие процессы могут изменить состояние файла. Вместо этого пользовательский код должен сразу открывать, читать или записывать файл и обрабатывать ошибку, если файл недоступен.

fsPromises.appendFile(path, data[, options])

Асинхронно добавляет данные в файл, создавая файл, если он ещё не существует. data может быть строкой или Buffer.

Если options — строка, она задаёт encoding.

Опция mode влияет только на вновь создаваемый файл. Подробнее см. fs.open().

path может быть задан как FileHandle, открытый для добавления (через fsPromises.open()).

fsPromises.chmod(path, mode)

Изменяет права доступа к файлу.

fsPromises.chown(path, uid, gid)

Изменяет владельца файла.

fsPromises.copyFile(src, dest[, mode])

  • src <string> | <Buffer> | <URL> Имя исходного файла для копирования
  • dest <string> | <Buffer> | <URL> Имя файла назначения для операции копирования
  • mode <integer> Необязательные модификаторы, задающие поведение операции копирования. Можно создать маску, состоящую из побитового ИЛИ двух или более значений (например, fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE) По умолчанию: 0.
    • fs.constants.COPYFILE_EXCL: Операция копирования завершится ошибкой, если dest уже существует.
    • fs.constants.COPYFILE_FICLONE: Операция копирования попытается создать reflink по схеме copy-on-write. Если платформа не поддерживает copy-on-write, будет использован резервный механизм копирования.
    • fs.constants.COPYFILE_FICLONE_FORCE: Операция копирования попытается создать reflink по схеме copy-on-write. Если платформа не поддерживает copy-on-write, операция завершится ошибкой.
  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Асинхронно копирует src в dest. По умолчанию dest будет перезаписан, если уже существует.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { copyFile, constants } from 'node:fs/promises';

try {
  await copyFile('source.txt', 'destination.txt');
  console.log('source.txt was copied to destination.txt');
} catch {
  console.error('The file could not be copied');
}

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
try {
  await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
  console.log('source.txt was copied to destination.txt');
} catch {
  console.error('The file could not be copied');
}

fsPromises.cp(src, dest[, options])

  • src <string> | <URL> Исходный путь для копирования.
  • dest <string> | <URL> Путь назначения для копирования.
  • options <Object>
    • dereference <boolean> Разыменовывать символические ссылки. По умолчанию: false.
    • errorOnExist <boolean> Если force равно false и место назначения существует, выбрасывать ошибку. По умолчанию: false.
    • filter <Function> Функция для фильтрации копируемых файлов и каталогов. Верните true, чтобы скопировать элемент, и false, чтобы его проигнорировать. Если игнорируется каталог, всё его содержимое также будет пропущено. Может также возвращать Promise, который разрешается в true или false По умолчанию: undefined.
      • src <string> Исходный путь для копирования.
      • dest <string> Путь назначения для копирования.
      • Возвращает: <boolean> | <Promise> Значение, приводимое к boolean, либо Promise, который исполняется таким значением.
    • force <boolean> Перезаписывать существующий файл или каталог. Операция копирования будет игнорировать ошибки, если установить false, а место назначения уже существует. Используйте опцию errorOnExist, чтобы изменить это поведение. По умолчанию: true.
    • mode <integer> Модификаторы операции копирования. По умолчанию: 0. См. флаг mode у fsPromises.copyFile().
    • preserveTimestamps <boolean> Если true, временные метки из src будут сохранены. По умолчанию: false.
    • recursive <boolean> Копировать каталоги рекурсивно. По умолчанию: false
    • verbatimSymlinks <boolean> Если true, разрешение путей для символических ссылок будет пропущено. По умолчанию: false
  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Асинхронно копирует всю структуру каталога из src в dest, включая подкаталоги и файлы.

При копировании одного каталога в другой globs не поддерживаются, а поведение аналогично cp dir1/ dir2/.

fsPromises.glob(pattern[, options])

  • pattern <string> | <string[]>
  • options <Object>
    • cwd <string> | <URL> Текущий рабочий каталог. По умолчанию: process.cwd()
    • exclude <Function> | <string[]> Функция для исключения файлов и каталогов из выборки либо список glob-шаблонов для исключения. Если передана функция, верните true, чтобы исключить элемент, и false, чтобы его включить. По умолчанию: undefined. Если передан массив строк, каждая строка должна быть glob-шаблоном, задающим исключаемые пути. Примечание: шаблоны с отрицанием (например, '!foo.js') не поддерживаются.
    • withFileTypes <boolean> Если true, glob возвращает пути в виде объектов Dirent; если false — в виде строк. По умолчанию: false.
  • Возвращает: <AsyncIterator> Асинхронный итератор, последовательно отдающий пути к файлам, соответствующим шаблону.
1
2
3
4
import { glob } from 'node:fs/promises';

for await (const entry of glob('**/*.js'))
  console.log(entry);
1
2
3
4
5
6
const { glob } = require('node:fs/promises');

(async () => {
  for await (const entry of glob('**/*.js'))
    console.log(entry);
})();

fsPromises.lchmod(path, mode)

Стабильность: 0 - устарело или набрало много негативных отзывов

Изменяет права доступа символической ссылки.

Этот метод реализован только в macOS.

fsPromises.lchown(path, uid, gid)

Изменяет владельца символической ссылки.

fsPromises.lutimes(path, atime, mtime)

Изменяет время доступа и модификации файла так же, как fsPromises.utimes(), с той разницей, что если путь указывает на символическую ссылку, то разыменование не выполняется: вместо этого изменяются временные метки самой символической ссылки.

fsPromises.link(existingPath, newPath)

Создаёт новую жёсткую ссылку с existingPath на newPath. Подробнее см. POSIX link(2).

fsPromises.lstat(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
  • Возвращает: <Promise> при успехе выполняется объектом fs.Stats для указанной символической ссылки path.

Эквивалентен fsPromises.stat(), если только path не указывает на символическую ссылку. В этом случае статистика берётся для самой ссылки, а не для файла, на который она указывает. Подробнее см. документацию POSIX lstat(2).

fsPromises.mkdir(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object> | <integer>
  • Возвращает: <Promise> при успехе выполняется с undefined, если recursive равно false, или с путём первого созданного каталога, если recursive равно true.

Асинхронно создаёт каталог.

Необязательный аргумент options может быть целым числом, задающим mode (права доступа и sticky-биты), либо объектом со свойствами mode и recursive, указывающим, нужно ли создавать родительские каталоги. Вызов fsPromises.mkdir() с path, который уже существует как каталог, приводит к отклонению промиса только когда recursive равно false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { mkdir } from 'node:fs/promises';

try {
  const projectFolder = new URL('./test/project/', import.meta.url);
  const createDir = await mkdir(projectFolder, { recursive: true });

  console.log(`created ${createDir}`);
} catch (err) {
  console.error(err.message);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const { mkdir } = require('node:fs/promises');
const { join } = require('node:path');

async function makeDirectory() {
  const projectFolder = join(__dirname, 'test', 'project');
  const dirCreation = await mkdir(projectFolder, { recursive: true });

  console.log(dirCreation);
  return dirCreation;
}

makeDirectory().catch(console.error);

fsPromises.mkdtemp(prefix[, options])

  • prefix <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • encoding <string> По умолчанию: 'utf8'
  • Возвращает: <Promise> при успехе выполняется строкой, содержащей путь файловой системы к только что созданному временному каталогу.

Создаёт уникальный временный каталог. Уникальное имя каталога формируется добавлением шести случайных символов в конец переданного prefix. Из-за различий между платформами избегайте завершающих символов X в prefix. Некоторые платформы, особенно BSD, могут возвращать более шести случайных символов и заменять завершающие X в prefix случайными символами.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим используемую кодировку символов.

1
2
3
4
5
6
7
8
9
import { mkdtemp } from 'node:fs/promises';
import { join } from 'node:path';
import { tmpdir } from 'node:os';

try {
  await mkdtemp(join(tmpdir(), 'foo-'));
} catch (err) {
  console.error(err);
}

Метод fsPromises.mkdtemp() добавляет шесть случайно выбранных символов непосредственно к строке prefix. Например, если дан каталог /tmp и требуется создать временный каталог внутри /tmp, prefix должен заканчиваться завершающим платформенно-зависимым разделителем пути (require('node:path').sep).

fsPromises.mkdtempDisposable(prefix[, options])

  • prefix <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • encoding <string> По умолчанию: 'utf8'
  • Возвращает: <Promise> при успехе выполняется промисом для асинхронно освобождаемого объекта:
    • path <string> путь созданного каталога
    • remove <AsyncFunction> функция, удаляющая созданный каталог
    • [Symbol.asyncDispose] <AsyncFunction> то же самое, что remove

Возвращаемый промис содержит асинхронно освобождаемый объект, чьё свойство path хранит путь к созданному каталогу. При освобождении объекта каталог и его содержимое будут удалены асинхронно, если они всё ещё существуют. Если каталог не удаётся удалить, освобождение завершится ошибкой. У объекта есть асинхронный метод remove(), выполняющий ту же задачу.

И эта функция, и функция освобождения у возвращаемого объекта являются асинхронными, поэтому использовать их следует через await + await using, например: await using dir = await fsPromises.mkdtempDisposable('prefix').

Подробнее см. документацию fsPromises.mkdtemp().

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим используемую кодировку символов.

fsPromises.open(path, flags[, mode])

Открывает FileHandle.

Подробнее см. документацию POSIX open(2).

Некоторые символы (< > : " / \ | ? *) в Windows зарезервированы, см. Имена файлов, путей и пространств имён. В NTFS, если имя файла содержит двоеточие, Node.js откроет поток файловой системы, как описано на этой странице Microsoft Learn.

fsPromises.opendir(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • encoding <string> | null По умолчанию: 'utf8'
    • bufferSize <number> число записей каталога, внутренне буферизуемых при чтении. Более высокие значения улучшают производительность, но увеличивают потребление памяти. По умолчанию: 32
    • recursive <boolean> возвращаемый Dir будет AsyncIterable, содержащим все вложенные файлы и каталоги. По умолчанию: false
  • Возвращает: <Promise> при успехе выполняется объектом fs.Dir.

Асинхронно открывает каталог для последовательного обхода. Подробнее см. POSIX opendir(3).

Создаёт fs.Dir со всеми методами чтения и очистки каталога.

Опция encoding задаёт кодировку для path при открытии и дальнейших операциях чтения.

Пример использования асинхронной итерации:

1
2
3
4
5
6
7
8
9
import { opendir } from 'node:fs/promises';

try {
  const dir = await opendir('./');
  for await (const dirent of dir)
    console.log(dirent.name);
} catch (err) {
  console.error(err);
}

При использовании асинхронного итератора объект fs.Dir будет автоматически закрыт после завершения итерации.

fsPromises.readdir(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • encoding <string> По умолчанию: 'utf8'
    • withFileTypes <boolean> По умолчанию: false
    • recursive <boolean> если true, читает содержимое каталога рекурсивно. В рекурсивном режиме будут перечислены все файлы, вложенные файлы и каталоги. По умолчанию: false.
  • Возвращает: <Promise> при успехе выполняется массивом имён файлов каталога, исключая '.' и '..'.

Читает содержимое каталога.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим кодировку имён файлов. Если encoding установлено в 'buffer', возвращаемые имена файлов будут объектами Buffer.

Если options.withFileTypes установлено в true, возвращаемый массив будет содержать объекты fs.Dirent.

1
2
3
4
5
6
7
8
9
import { readdir } from 'node:fs/promises';

try {
  const files = await readdir(path);
  for (const file of files)
    console.log(file);
} catch (err) {
  console.error(err);
}

fsPromises.readFile(path[, options])

Асинхронно читает всё содержимое файла.

Если кодировка не указана (через options.encoding), данные возвращаются как объект Buffer. В противном случае это будет строка.

Если options — строка, она задаёт кодировку.

Если path указывает на каталог, поведение fsPromises.readFile() зависит от платформы. В macOS, Linux и Windows промис будет отклонён с ошибкой. В FreeBSD будет возвращено представление содержимого каталога.

Пример чтения файла package.json, расположенного в том же каталоге, что и выполняемый код:

1
2
3
4
5
6
7
8
import { readFile } from 'node:fs/promises';
try {
  const filePath = new URL('./package.json', import.meta.url);
  const contents = await readFile(filePath, { encoding: 'utf8' });
  console.log(contents);
} catch (err) {
  console.error(err.message);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const { readFile } = require('node:fs/promises');
const { resolve } = require('node:path');
async function logFile() {
  try {
    const filePath = resolve('./package.json');
    const contents = await readFile(filePath, { encoding: 'utf8' });
    console.log(contents);
  } catch (err) {
    console.error(err.message);
  }
}
logFile();

Текущий readFile можно прервать с помощью AbortSignal. Если запрос прерван, возвращаемый промис отклоняется с AbortError:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { readFile } from 'node:fs/promises';

try {
  const controller = new AbortController();
  const { signal } = controller;
  const promise = readFile(fileName, { signal });

  // Abort the request before the promise settles.
  controller.abort();

  await promise;
} catch (err) {
  // When a request is aborted - err is an AbortError
  console.error(err);
}

Прерывание текущего запроса не отменяет отдельные запросы операционной системы, а лишь внутреннюю буферизацию, которую выполняет fs.readFile.

Любой указанный FileHandle должен поддерживать чтение.

fsPromises.readlink(path[, options])

Читает содержимое символьной ссылки path. Подробнее см. POSIX readlink(2). При успехе промис даёт строку linkString.

Необязательный options — строка с кодировкой или объект с полем encoding. При encoding: 'buffer' путь к ссылке возвращается как Buffer.

fsPromises.realpath(path[, options])

Определяет фактическое расположение path, используя ту же семантику, что и функция fs.realpath.native().

Поддерживаются только пути, которые можно преобразовать в строки UTF-8.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим кодировку символов для пути. Если encoding установлено в 'buffer', возвращаемый путь будет передан как объект Buffer.

В Linux, когда Node.js слинкован с musl libc, для работы этой функции файловая система procfs должна быть смонтирована в /proc. У glibc такого ограничения нет.

fsPromises.rename(oldPath, newPath)

Переименовывает oldPath в newPath.

fsPromises.rmdir(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object> в настоящий момент никаких опций не предоставляется. Раньше существовали опции recursive, maxBusyTries и emfileWait, но они были устаревшими и удалены. Аргумент options по-прежнему принимается для обратной совместимости, но не используется.
  • Возвращает: <Promise> При успешном выполнении исполняется значением undefined.

Удаляет каталог, указанный в path.

Использование fsPromises.rmdir() для файла (а не каталога) приводит к отклонению промиса с ошибкой ENOENT в Windows и ENOTDIR в POSIX.

Чтобы получить поведение, аналогичное Unix-команде rm -rf, используйте fsPromises.rm() с опциями { recursive: true, force: true }.

fsPromises.rm(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • force <boolean> если true, исключения игнорируются, если path не существует. По умолчанию: false.
    • maxRetries <integer> если возникает ошибка EBUSY, EMFILE, ENFILE, ENOTEMPTY или EPERM, Node.js повторяет операцию, линейно увеличивая ожидание на retryDelay миллисекунд при каждой попытке. Эта опция задаёт число повторов. Игнорируется, если recursive не равно true. По умолчанию: 0.
    • recursive <boolean> если true, выполняется рекурсивное удаление каталога. В рекурсивном режиме операции повторяются при сбоях. По умолчанию: false.
    • retryDelay <integer> количество миллисекунд ожидания между повторными попытками. Игнорируется, если recursive не равно true. По умолчанию: 100.
  • Возвращает: <Promise> при успехе выполняется с undefined.

Удаляет файлы и каталоги (по образцу стандартной POSIX-утилиты rm).

fsPromises.stat(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
    • throwIfNoEntry <boolean> следует ли выбрасывать исключение, если запись файловой системы не существует, вместо возврата undefined. По умолчанию: true.
  • Возвращает: <Promise> при успехе выполняется объектом fs.Stats для указанного path.

fsPromises.statfs(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.StatFs иметь тип bigint. По умолчанию: false.
  • Возвращает: <Promise> при успехе выполняется объектом fs.StatFs для указанного path.

fsPromises.symlink(target, path[, type])

Создаёт символическую ссылку.

Аргумент type используется только в Windows и может иметь одно из значений: 'dir', 'file' или 'junction'. Если type равен null, Node.js автоматически определит тип target и использует 'file' или 'dir'. Если target не существует, будет использовано 'file'. Точки соединения Windows требуют, чтобы путь назначения был абсолютным. При использовании 'junction' аргумент target автоматически нормализуется к абсолютному пути. Точки соединения на томах NTFS могут указывать только на каталоги.

fsPromises.truncate(path[, len])

Усекает (или увеличивает) длину содержимого по пути path до len байт.

fsPromises.unlink(path)

Если path указывает на символическую ссылку, ссылка будет удалена без влияния на файл или каталог, на который она указывает. Если path указывает на путь к файлу, который не является символической ссылкой, файл будет удалён. Подробнее см. POSIX unlink(2).

fsPromises.utimes(path, atime, mtime)

Изменяет временные метки файловой системы для объекта, на который указывает path.

Аргументы atime и mtime подчиняются следующим правилам:

  • Значениями могут быть числа, представляющие время Unix epoch, объекты Date или числовые строки вроде '123456789.0'.
  • Если значение нельзя преобразовать в число либо это NaN, Infinity или -Infinity, будет выброшен Error.

fsPromises.watch(filename[, options])

  • filename <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • persistent <boolean> указывает, должен ли процесс продолжать работу, пока файлы отслеживаются. По умолчанию: true.
    • recursive <boolean> указывает, нужно ли отслеживать все подкаталоги или только текущий каталог. Применяется, когда указан каталог, и только на поддерживаемых платформах (см. предостережения). По умолчанию: false.
    • encoding <string> задаёт кодировку символов, которая будет использоваться для имени файла, передаваемого слушателю. По умолчанию: 'utf8'.
    • signal <AbortSignal> AbortSignal, используемый для указания, когда наблюдатель должен остановиться.
    • maxQueue <number> задаёт число событий, которое может быть помещено в очередь между итерациями возвращаемого AsyncIterator. По умолчанию: 2048.
    • overflow <string> либо 'ignore', либо 'throw', когда событий для очереди больше, чем допускает maxQueue. 'ignore' означает, что события переполнения будут отброшены и будет выдано предупреждение, а 'throw' означает выброс исключения. По умолчанию: 'ignore'.
    • ignore <string> | <RegExp> | <Function> | <Array> шаблоны для игнорирования. Строки являются glob-шаблонами (с использованием minimatch), шаблоны RegExp проверяются по имени файла, а функции получают имя файла и возвращают true, если его нужно игнорировать. По умолчанию: undefined.
  • Возвращает: <AsyncIterator> объектов со свойствами:
    • eventType <string> тип изменения
    • filename <string> | <Buffer> | null имя изменившегося файла

Возвращает асинхронный итератор, отслеживающий изменения для filename, где filename может быть как файлом, так и каталогом.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const { watch } = require('node:fs/promises');

const ac = new AbortController();
const { signal } = ac;
setTimeout(() => ac.abort(), 10000);

(async () => {
    try {
        const watcher = watch(__filename, { signal });
        for await (const event of watcher)
            console.log(event);
    } catch (err) {
        if (err.name === 'AbortError') return;
        throw err;
    }
})();

На большинстве платформ событие 'rename' генерируется всякий раз, когда имя файла появляется или исчезает в каталоге.

Все предостережения для fs.watch() также относятся к fsPromises.watch().

fsPromises.writeFile(file, data[, options])

Асинхронно записывает данные в файл, заменяя файл, если он уже существует. data может быть строкой, буфером, объектом AsyncIterable или объектом Iterable.

Опция encoding игнорируется, если data является буфером.

Если options — строка, она задаёт кодировку.

Параметр mode влияет только на вновь создаваемый файл. Подробнее см. в fs.open().

Любой указанный FileHandle должен поддерживать запись.

Небезопасно использовать fsPromises.writeFile() несколько раз для одного и того же файла, не дожидаясь завершения промиса.

Как и fsPromises.readFile, fsPromises.writeFile — это удобный метод, который внутри выполняет несколько вызовов write, чтобы записать переданный буфер. Для кода, чувствительного к производительности, лучше использовать fs.createWriteStream() или filehandle.createWriteStream().

Можно использовать AbortSignal, чтобы отменить fsPromises.writeFile(). Отмена выполняется по принципу "best effort", и некоторое количество данных, вероятно, всё равно будет записано.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { writeFile } from 'node:fs/promises';
import { Buffer } from 'node:buffer';

try {
  const controller = new AbortController();
  const { signal } = controller;
  const data = new Uint8Array(Buffer.from('Hello Node.js'));
  const promise = writeFile('message.txt', data, { signal });

  // Abort the request before the promise settles.
  controller.abort();

  await promise;
} catch (err) {
  // When a request is aborted - err is an AbortError
  console.error(err);
}

Прерывание выполняющегося запроса не отменяет отдельные запросы операционной системы, а лишь внутреннюю буферизацию, которую выполняет fs.writeFile.

fsPromises.constants

Возвращает объект, содержащий часто используемые константы для операций файловой системы. Этот объект совпадает с fs.constants. Подробнее см. в разделе Константы FS.

API обратных вызовов

API обратных вызовов выполняют все операции асинхронно, не блокируя цикл событий, а затем вызывают функцию обратного вызова при завершении или ошибке.

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

fs.access(path[, mode], callback)

Проверяет права пользователя на файл или каталог, указанный в path. Аргумент mode — необязательное целое число, задающее выполняемые проверки доступности. mode должен быть либо значением fs.constants.F_OK, либо маской, составленной побитовым ИЛИ из fs.constants.R_OK, fs.constants.W_OK и fs.constants.X_OK (например, fs.constants.W_OK | fs.constants.R_OK). Возможные значения mode см. в разделе Константы доступа к файлам.

Последний аргумент, callback, — это функция обратного вызова, вызываемая с возможным аргументом ошибки. Если какая-либо из проверок доступности завершается неудачей, аргумент ошибки будет объектом Error. В следующих примерах проверяется, существует ли package.json и доступен ли он для чтения или записи.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { access, constants } from 'node:fs';

const file = 'package.json';

// Check if the file exists in the current directory.
access(file, constants.F_OK, (err) => {
  console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
});

// Check if the file is readable.
access(file, constants.R_OK, (err) => {
  console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);
});

// Check if the file is writable.
access(file, constants.W_OK, (err) => {
  console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);
});

// Check if the file is readable and writable.
access(file, constants.R_OK | constants.W_OK, (err) => {
  console.log(`${file} ${err ? 'is not' : 'is'} readable and writable`);
});

Не используйте fs.access() для проверки доступности файла перед вызовом fs.open(), fs.readFile() или fs.writeFile(). Это создаёт состояние гонки, поскольку между двумя вызовами другой процесс может изменить состояние файла. Вместо этого код пользователя должен напрямую открывать/читать/записывать файл и обрабатывать ошибку, возникающую, если файл недоступен.

write (NOT RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { access, open, close } from 'node:fs';

access('myfile', (err) => {
  if (!err) {
    console.error('myfile already exists');
    return;
  }

  open('myfile', 'wx', (err, fd) => {
    if (err) throw err;

    try {
      writeMyData(fd);
    } finally {
      close(fd, (err) => {
        if (err) throw err;
      });
    }
  });
});

write (RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { open, close } from 'node:fs';

open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  try {
    writeMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
});

read (NOT RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { access, open, close } from 'node:fs';
access('myfile', (err) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  open('myfile', 'r', (err, fd) => {
    if (err) throw err;

    try {
      readMyData(fd);
    } finally {
      close(fd, (err) => {
        if (err) throw err;
      });
    }
  });
});

read (RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { open, close } from 'node:fs';

open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  try {
    readMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
});

Примеры выше с пометкой "not recommended" сначала проверяют доступность файла, а затем используют его; примеры с пометкой "recommended" лучше, потому что работают с файлом напрямую и при необходимости обрабатывают ошибку.

В общем случае проверяйте доступность файла только тогда, когда сам файл не будет использоваться напрямую, например если его доступность служит сигналом от другого процесса.

В Windows политики управления доступом (ACL) для каталога могут ограничивать доступ к файлу или каталогу. Однако функция fs.access() не проверяет ACL и потому может сообщить, что путь доступен, даже если ACL запрещает пользователю чтение или запись.

fs.appendFile(path, data[, options], callback)

Асинхронно добавляет данные в файл, создавая его, если он ещё не существует. data может быть строкой или Buffer.

Опция mode влияет только на вновь создаваемый файл. Подробнее см. fs.open().

1
2
3
4
5
6
import { appendFile } from 'node:fs';

appendFile('message.txt', 'data to append', (err) => {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

Если options — строка, она задаёт кодировку:

1
2
3
import { appendFile } from 'node:fs';

appendFile('message.txt', 'data to append', 'utf8', callback);

path может быть указан как числовой файловый дескриптор, открытый для добавления (через fs.open() или fs.openSync()). Такой файловый дескриптор не закрывается автоматически.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import { open, close, appendFile } from 'node:fs';

function closeFd(fd) {
  close(fd, (err) => {
    if (err) throw err;
  });
}

open('message.txt', 'a', (err, fd) => {
  if (err) throw err;

  try {
    appendFile(fd, 'data to append', 'utf8', (err) => {
      closeFd(fd);
      if (err) throw err;
    });
  } catch (err) {
    closeFd(fd);
    throw err;
  }
});

fs.chmod(path, mode, callback)

Асинхронно изменяет права доступа к файлу. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX chmod(2).

1
2
3
4
5
6
import { chmod } from 'node:fs';

chmod('my_file.txt', 0o775, (err) => {
  if (err) throw err;
  console.log('The permissions for file "my_file.txt" have been changed!');
});

File modes

Аргумент mode, используемый в методах fs.chmod() и fs.chmodSync(), представляет собой числовую битовую маску, создаваемую с помощью побитового OR следующих констант:

Константа Восьмеричное значение Описание
fs.constants.S_IRUSR 0o400 чтение владельцем
fs.constants.S_IWUSR 0o200 запись владельцем
fs.constants.S_IXUSR 0o100 выполнение/поиск владельцем
fs.constants.S_IRGRP 0o40 чтение группой
fs.constants.S_IWGRP 0o20 запись группой
fs.constants.S_IXGRP 0o10 выполнение/поиск группой
fs.constants.S_IROTH 0o4 чтение остальными
fs.constants.S_IWOTH 0o2 запись остальными
fs.constants.S_IXOTH 0o1 выполнение/поиск остальными

Более простой способ задать mode — использовать последовательность из трёх восьмеричных цифр (например, 765). Самая левая цифра (7 в примере) задаёт права для владельца файла. Средняя цифра (6 в примере) задаёт права для группы. Самая правая цифра (5 в примере) задаёт права для остальных.

Число Описание
7 чтение, запись и выполнение
6 чтение и запись
5 чтение и выполнение
4 только чтение
3 запись и выполнение
2 только запись
1 только выполнение
0 нет прав

Например, восьмеричное значение 0o765 означает:

  • владелец может читать, записывать и выполнять файл;
  • группа может читать и записывать файл;
  • остальные могут читать и выполнять файл.

Если использовать необработанные числа там, где ожидаются режимы файлов, любое значение больше 0o777 может приводить к платформенно-зависимому поведению, для которого не гарантируется единообразная работа. Поэтому константы вроде S_ISVTX, S_ISGID или S_ISUID не экспортируются через fs.constants.

Предостережение: в Windows можно изменить только право на запись, а различие между правами группы, владельца и остальных не реализовано.

fs.chown(path, uid, gid, callback)

Асинхронно изменяет владельца и группу файла. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX chown(2).

fs.close(fd[, callback])

Закрывает файловый дескриптор. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Вызов fs.close() для любого файлового дескриптора (fd), который в данный момент используется в какой-либо другой операции fs, может привести к неопределённому поведению.

Подробнее см. POSIX close(2).

fs.copyFile(src, dest[, mode], callback)

  • src <string> | <Buffer> | <URL> имя исходного файла для копирования
  • dest <string> | <Buffer> | <URL> имя целевого файла операции копирования
  • mode <integer> модификаторы операции копирования. По умолчанию: 0.
  • callback <Function>

Асинхронно копирует src в dest. По умолчанию dest будет перезаписан, если он уже существует. В callback не передаются никакие аргументы, кроме возможного исключения. Node.js не даёт никаких гарантий атомарности операции копирования. Если ошибка возникает после открытия целевого файла для записи, Node.js попытается удалить его.

mode — необязательное целое число, задающее поведение операции копирования. Можно создать маску из двух или более значений, объединённых побитовым ИЛИ (например, fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

  • fs.constants.COPYFILE_EXCL: операция копирования завершится ошибкой, если dest уже существует.
  • fs.constants.COPYFILE_FICLONE: операция копирования попытается создать reflink с копированием по записи. Если платформа не поддерживает copy-on-write, используется запасной механизм копирования.
  • fs.constants.COPYFILE_FICLONE_FORCE: операция копирования попытается создать reflink с копированием по записи. Если платформа не поддерживает copy-on-write, операция завершится ошибкой.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { copyFile, constants } from 'node:fs';

function callback(err) {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
}

// destination.txt will be created or overwritten by default.
copyFile('source.txt', 'destination.txt', callback);

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback);

fs.cp(src, dest[, options], callback)

  • src <string> | <URL> Исходный путь для копирования.
  • dest <string> | <URL> Путь назначения для копирования.
  • options <Object>
    • dereference <boolean> Разыменовывать символические ссылки. По умолчанию: false.
    • errorOnExist <boolean> Если force равно false и место назначения существует, выбрасывать ошибку. По умолчанию: false.
    • filter <Function> Функция для фильтрации копируемых файлов и каталогов. Верните true, чтобы скопировать элемент, и false, чтобы его проигнорировать. Если игнорируется каталог, всё его содержимое также будет пропущено. Может также возвращать Promise, который разрешается в true или false По умолчанию: undefined.
      • src <string> Исходный путь для копирования.
      • dest <string> Путь назначения для копирования.
      • Возвращает: <boolean> | <Promise> Значение, приводимое к boolean, либо Promise, который исполняется таким значением.
    • force <boolean> Перезаписывать существующий файл или каталог. Операция копирования будет игнорировать ошибки, если установить false, а место назначения уже существует. Используйте опцию errorOnExist, чтобы изменить это поведение. По умолчанию: true.
    • mode <integer> Модификаторы операции копирования. По умолчанию: 0. См. флаг mode у fs.copyFile().
    • preserveTimestamps <boolean> Если true, временные метки из src будут сохранены. По умолчанию: false.
    • recursive <boolean> Копировать каталоги рекурсивно. По умолчанию: false
    • verbatimSymlinks <boolean> Если true, разрешение путей для символических ссылок будет пропущено. По умолчанию: false
  • callback <Function>

Асинхронно копирует всю структуру каталогов из src в dest, включая подкаталоги и файлы.

При копировании одного каталога в другой glob-шаблоны не поддерживаются, а поведение аналогично cp dir1/ dir2/.

fs.createReadStream(path[, options])

options может включать значения start и end, чтобы читать диапазон байтов файла, а не весь файл целиком. И start, и end включаются в диапазон, отсчёт начинается с 0, допустимые значения находятся в диапазоне [0, Number.MAX_SAFE_INTEGER]. Если указан fd, а start опущен или равен undefined, fs.createReadStream() читает последовательно от текущей позиции в файле. encoding может быть любым из значений, принимаемых Buffer.

Если указан fd, ReadStream игнорирует аргумент path и использует переданный файловый дескриптор. Это означает, что событие 'open' сгенерировано не будет. fd должен быть блокирующим; неблокирующие fd следует передавать в net.Socket.

Если fd указывает на символьное устройство, поддерживающее только блокирующее чтение (например, клавиатуру или звуковую карту), операции чтения не завершаются, пока данные не станут доступны. Это может помешать завершению процесса и естественному закрытию потока.

По умолчанию поток генерирует событие 'close' после уничтожения. Чтобы изменить это поведение, установите опцию emitClose в false.

Через опцию fs можно переопределить соответствующие реализации fs для open, read и close. При передаче опции fs переопределение read обязательно. Если fd не указан, обязательно также переопределение open. Если autoClose равно true, обязательно также переопределение close.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { createReadStream } from 'node:fs';

// Create a stream from some character device.
const stream = createReadStream('/dev/input/event0');
setTimeout(() => {
  stream.close(); // This may not close the stream.
  // Artificially marking end-of-stream, as if the underlying resource had
  // indicated end-of-file by itself, allows the stream to close.
  // This does not cancel pending read operations, and if there is such an
  // operation, the process may still not be able to exit successfully
  // until it finishes.
  stream.push(null);
  stream.read(0);
}, 100);

Если autoClose равно false, файловый дескриптор не будет закрыт даже при ошибке. Приложение само отвечает за его закрытие и за отсутствие утечек файловых дескрипторов. Если autoClose установлено в true (поведение по умолчанию), при 'error' или 'end' файловый дескриптор будет закрыт автоматически.

mode задаёт режим файла (права доступа и sticky-биты), но только если файл был создан.

Пример чтения последних 10 байтов файла длиной 100 байтов:

1
2
3
import { createReadStream } from 'node:fs';

createReadStream('sample.txt', { start: 90, end: 99 });

Если options — строка, она задаёт кодировку.

fs.createWriteStream(path[, options])

options также может включать опцию start, позволяющую писать данные в некоторую позицию после начала файла; допустимые значения лежат в диапазоне [0, Number.MAX_SAFE_INTEGER]. Чтобы изменять файл, а не заменять его, может потребоваться установить flags в r+, а не использовать значение по умолчанию w. encoding может быть любым из значений, принимаемых Buffer.

Если autoClose установлено в true (поведение по умолчанию), при 'error' или 'finish' файловый дескриптор будет закрыт автоматически. Если autoClose равно false, файловый дескриптор не будет закрыт даже при ошибке. Приложение само отвечает за его закрытие и за отсутствие утечек файловых дескрипторов.

По умолчанию поток генерирует событие 'close' после уничтожения. Чтобы изменить это поведение, установите опцию emitClose в false.

Через опцию fs можно переопределить соответствующие реализации fs для open, write, writev и close. Переопределение write() без writev() может снизить производительность, потому что некоторые оптимизации (_writev()) будут отключены. При передаче опции fs требуется переопределить как минимум одну из функций write и writev. Если опция fd не передана, обязательно также переопределение open. Если autoClose равно true, обязательно также переопределение close.

Как и fs.ReadStream, если указан fd, fs.WriteStream игнорирует аргумент path и использует переданный файловый дескриптор. Это означает, что событие 'open' сгенерировано не будет. fd должен быть блокирующим; неблокирующие fd следует передавать в net.Socket.

Если options — строка, она задаёт кодировку.

fs.exists(path, callback)

Стабильность: 0 - устарело или набрало много негативных отзывов

Используйте fs.stat() или fs.access().

Проверяет через файловую систему, существует ли элемент по указанному пути path. Затем вызывает callback со значением true или false:

1
2
3
4
5
import { exists } from 'node:fs';

exists('/etc/passwd', (e) => {
  console.log(e ? 'it exists' : 'no passwd!');
});

Параметры этого callback не согласованы с другими callback Node.js. Обычно первый параметр callback в Node.js — это err, за которым при необходимости следуют другие параметры. Callback fs.exists() имеет только один логический параметр. Это одна из причин, почему вместо fs.exists() рекомендуется использовать fs.access().

Если path является символической ссылкой, она будет разыменована. Поэтому, если path существует, но указывает на несуществующий элемент, callback получит значение false.

Использовать fs.exists() для проверки существования файла перед вызовом fs.open(), fs.readFile() или fs.writeFile() не рекомендуется. Это создаёт состояние гонки, поскольку между двумя вызовами другой процесс может изменить состояние файла. Вместо этого код пользователя должен напрямую открывать/читать/записывать файл и обрабатывать ошибку, возникающую, если файл не существует.

write (NOT RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { exists, open, close } from 'node:fs';

exists('myfile', (e) => {
  if (e) {
    console.error('myfile already exists');
  } else {
    open('myfile', 'wx', (err, fd) => {
      if (err) throw err;

      try {
        writeMyData(fd);
      } finally {
        close(fd, (err) => {
          if (err) throw err;
        });
      }
    });
  }
});

write (RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { open, close } from 'node:fs';
open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  try {
    writeMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
});

read (NOT RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { open, close, exists } from 'node:fs';

exists('myfile', (e) => {
  if (e) {
    open('myfile', 'r', (err, fd) => {
      if (err) throw err;

      try {
        readMyData(fd);
      } finally {
        close(fd, (err) => {
          if (err) throw err;
        });
      }
    });
  } else {
    console.error('myfile does not exist');
  }
});

read (RECOMMENDED)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { open, close } from 'node:fs';

open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  try {
    readMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
});

Примеры выше с пометкой "not recommended" сначала проверяют существование файла, а затем используют его; примеры с пометкой "recommended" лучше, потому что работают с файлом напрямую и при необходимости обрабатывают ошибку.

В общем случае проверяйте существование файла только тогда, когда сам файл не будет использоваться напрямую, например если его наличие служит сигналом от другого процесса.

fs.fchmod(fd, mode, callback)

Устанавливает права доступа к файлу. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX fchmod(2).

fs.fchown(fd, uid, gid, callback)

Устанавливает владельца файла. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX fchown(2).

fs.fdatasync(fd, callback)

Принудительно переводит все текущие поставленные в очередь операции ввода-вывода, связанные с файлом, в состояние синхронизированного завершения ввода-вывода на уровне операционной системы. Подробнее см. документацию POSIX fdatasync(2). В callback завершения не передаются никакие аргументы, кроме возможного исключения.

fs.fstat(fd[, options], callback)

Вызывает callback с объектом fs.Stats для файлового дескриптора.

Подробнее см. POSIX fstat(2).

fs.fsync(fd, callback)

Запрашивает сброс всех данных открытого файлового дескриптора на устройство хранения. Конкретная реализация зависит от операционной системы и устройства. Подробнее см. документацию POSIX fsync(2). В callback завершения не передаются никакие аргументы, кроме возможного исключения.

fs.ftruncate(fd[, len], callback)

Усекает файловый дескриптор. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX ftruncate(2).

Если файл, на который указывает файловый дескриптор, был длиннее len байт, в файле будут сохранены только первые len байт.

Например, следующая программа сохраняет только первые четыре байта файла:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import { open, close, ftruncate } from 'node:fs';

function closeFd(fd) {
  close(fd, (err) => {
    if (err) throw err;
  });
}

open('temp.txt', 'r+', (err, fd) => {
  if (err) throw err;

  try {
    ftruncate(fd, 4, (err) => {
      closeFd(fd);
      if (err) throw err;
    });
  } catch (err) {
    closeFd(fd);
    if (err) throw err;
  }
});

Если до этого файл был короче len байт, он будет расширен, а добавленная часть заполнена нулевыми байтами ('\0'):

Если len отрицательно, будет использовано значение 0.

fs.futimes(fd, atime, mtime, callback)

Изменяет временные метки файловой системы для объекта, на который ссылается переданный файловый дескриптор. См. fs.utimes().

fs.glob(pattern[, options], callback)

  • pattern <string> | <string[]>

  • options <Object>

    • cwd <string> | <URL> Текущий рабочий каталог. По умолчанию: process.cwd()
    • exclude <Function> | <string[]> Функция для исключения файлов и каталогов из выборки либо список glob-шаблонов для исключения. Если передана функция, верните true, чтобы исключить элемент, и false, чтобы его включить. По умолчанию: undefined. Если передан массив строк, каждая строка должна быть glob-шаблоном, задающим исключаемые пути. Примечание: шаблоны с отрицанием (например, '!foo.js') не поддерживаются.
    • withFileTypes <boolean> Если true, glob возвращает пути в виде объектов Dirent; если false — в виде строк. По умолчанию: false.
  • callback <Function>

  • Получает пути к файлам, соответствующим указанному шаблону.

1
2
3
4
5
6
import { glob } from 'node:fs';

glob('**/*.js', (err, matches) => {
  if (err) throw err;
  console.log(matches);
});
1
2
3
4
5
6
const { glob } = require('node:fs');

glob('**/*.js', (err, matches) => {
  if (err) throw err;
  console.log(matches);
});

fs.lchmod(path, mode, callback)

Stability: 0 - Deprecated

Изменяет права доступа символической ссылки. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Этот метод реализован только в macOS.

Подробнее см. POSIX lchmod(2).

fs.lchown(path, uid, gid, callback)

Устанавливает владельца символической ссылки. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX lchown(2).

fs.lutimes(path, atime, mtime, callback)

Изменяет время доступа и модификации файла так же, как fs.utimes(), с той разницей, что если путь указывает на символическую ссылку, то разыменование не выполняется: вместо этого изменяются временные метки самой символической ссылки.

В callback завершения не передаются никакие аргументы, кроме возможного исключения.

fs.link(existingPath, newPath, callback)

Создаёт новую жёсткую ссылку с existingPath на newPath. Подробнее см. POSIX link(2). В callback завершения не передаются никакие аргументы, кроме возможного исключения.

fs.lstat(path[, options], callback)

Получает fs.Stats для символической ссылки, на которую указывает путь. Callback получает два аргумента (err, stats), где stats — объект fs.Stats. lstat() идентичен stat(), за исключением того, что если path является символической ссылкой, статистика берётся для самой ссылки, а не для файла, на который она указывает.

Подробнее см. POSIX lstat(2).

fs.mkdir(path[, options], callback)

Асинхронно создаёт каталог.

Callback получает возможное исключение и, если recursive равно true, путь к первому созданному каталогу, (err[, path]). path всё ещё может быть undefined, когда recursive равно true, если каталог не был создан (например, если он уже существовал).

Необязательный аргумент options может быть целым числом, задающим mode (права доступа и sticky-биты), либо объектом со свойствами mode и recursive, указывающим, нужно ли создавать родительские каталоги. Вызов fs.mkdir() с path, который уже существует как каталог, приводит к ошибке только если recursive равно false. Если recursive равно false и каталог существует, возникает ошибка EEXIST.

1
2
3
4
5
6
import { mkdir } from 'node:fs';

// Create ./tmp/a/apple, regardless of whether ./tmp and ./tmp/a exist.
mkdir('./tmp/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});

В Windows использование fs.mkdir() для корневого каталога даже с рекурсией приведёт к ошибке:

1
2
3
4
5
import { mkdir } from 'node:fs';

mkdir('/', { recursive: true }, (err) => {
  // => [Error: EPERM: operation not permitted, mkdir 'C:\']
});

Подробнее см. POSIX mkdir(2).

fs.mkdtemp(prefix[, options], callback)

Создаёт уникальный временный каталог.

Генерирует шесть случайных символов, добавляемых в конец обязательного prefix, чтобы создать уникальный временный каталог. Из-за различий между платформами избегайте завершающих символов X в prefix. Некоторые платформы, особенно BSD, могут возвращать более шести случайных символов и заменять завершающие X в prefix случайными символами.

Путь к созданному каталогу передаётся строкой во второй параметр callback.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим используемую кодировку символов.

1
2
3
4
5
6
7
8
9
import { mkdtemp } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';

mkdtemp(join(tmpdir(), 'foo-'), (err, directory) => {
  if (err) throw err;
  console.log(directory);
  // Prints: /tmp/foo-itXde2 or C:\Users\...\AppData\Local\Temp\foo-itXde2
});

Метод fs.mkdtemp() добавляет шесть случайно выбранных символов непосредственно к строке prefix. Например, если дан каталог /tmp и требуется создать временный каталог внутри /tmp, prefix должен заканчиваться завершающим платформенно-зависимым разделителем пути (require('node:path').sep).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { tmpdir } from 'node:os';
import { mkdtemp } from 'node:fs';

// The parent directory for the new temporary directory
const tmpDir = tmpdir();

// This method is *INCORRECT*:
mkdtemp(tmpDir, (err, directory) => {
  if (err) throw err;
  console.log(directory);
  // Will print something similar to `/tmpabc123`.
  // A new temporary directory is created at the file system root
  // rather than *within* the /tmp directory.
});

// This method is *CORRECT*:
import { sep } from 'node:path';
mkdtemp(`${tmpDir}${sep}`, (err, directory) => {
  if (err) throw err;
  console.log(directory);
  // Will print something similar to `/tmp/abc123`.
  // A new temporary directory is created within
  // the /tmp directory.
});

fs.open(path[, flags[, mode]], callback)

Асинхронное открытие файла. Подробнее см. POSIX open(2).

mode задаёт режим файла (права доступа и sticky-биты), но только если файл был создан. В Windows можно управлять только правом на запись; см. fs.chmod().

Callback получает два аргумента (err, fd).

Некоторые символы (< > : " / \ | ? *) в Windows зарезервированы, см. Имена файлов, путей и пространств имён. В NTFS, если имя файла содержит двоеточие, Node.js откроет поток файловой системы, как описано на этой странице Microsoft Learn.

Такое же поведение наблюдается и у функций, основанных на fs.open(): fs.writeFile(), fs.readFile() и т. д.

fs.openAsBlob(path[, options])

Возвращает Blob, данные которого опираются на указанный файл.

Файл нельзя изменять после создания Blob. Любые изменения приведут к ошибке чтения данных Blob с DOMException. При создании Blob и перед каждым чтением выполняются синхронные операции stat над файлом, чтобы определить, были ли данные файла изменены на диске.

1
2
3
4
5
import { openAsBlob } from 'node:fs';

const blob = await openAsBlob('the.file.txt');
const ab = await blob.arrayBuffer();
blob.stream();
1
2
3
4
5
6
7
const { openAsBlob } = require('node:fs');

(async () => {
  const blob = await openAsBlob('the.file.txt');
  const ab = await blob.arrayBuffer();
  blob.stream();
})();

fs.opendir(path[, options], callback)

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • encoding <string> | null По умолчанию: 'utf8'
    • bufferSize <number> число записей каталога, внутренне буферизуемых при чтении. Более высокие значения улучшают производительность, но увеличивают потребление памяти. По умолчанию: 32
    • recursive <boolean> По умолчанию: false
  • callback <Function>

Асинхронно открывает каталог. Подробнее см. POSIX opendir(3).

Создаёт fs.Dir со всеми методами чтения и очистки каталога.

Опция encoding задаёт кодировку для path при открытии и дальнейших операциях чтения.

fs.read(fd, buffer, offset, length, position, callback)

  • fd <integer>
  • buffer <Buffer> | <TypedArray> | <DataView> буфер, в который будут записаны данные
  • offset <integer> позиция в buffer, в которую будут записаны данные
  • length <integer> количество байтов для чтения
  • position <integer> | <bigint> | null указывает, с какого места в файле начинать чтение. Если position равно null или -1, данные читаются с текущей позиции в файле, и позиция файла будет обновлена. Если position — неотрицательное целое число, позиция файла не изменится.
  • callback <Function>

Читает данные из файла, указанного в fd.

Callback получает три аргумента: (err, bytesRead, buffer).

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

Если метод вызывается в версии, обёрнутой через util.promisify(), он возвращает промис, исполняемый объектом Object со свойствами bytesRead и buffer.

Метод fs.read() читает данные из файла, указанного файловым дескриптором (fd). Аргумент length указывает максимальное количество байтов, которое Node.js попытается прочитать из ядра. Однако фактическое количество прочитанных байтов (bytesRead) по разным причинам может быть меньше указанного length.

Например:

  • если файл короче указанного length, в bytesRead будет записано фактическое число прочитанных байтов;
  • если файл достигает EOF (конца файла) до заполнения буфера, Node.js прочитает все доступные байты до EOF, а параметр bytesRead в callback укажет фактическое количество прочитанных байтов, которое может быть меньше заданного length;
  • если файл находится в медленной сетевой файловой системе или при чтении возникает любая другая проблема, bytesRead может быть меньше указанного length.

Поэтому при использовании fs.read() важно проверять значение bytesRead, чтобы определить, сколько байтов действительно было прочитано из файла. В зависимости от логики приложения может потребоваться обработка случаев, когда bytesRead меньше указанного length, например через оборачивание вызова чтения в цикл, если требуется минимум определённого количества байтов.

Это поведение похоже на функцию POSIX preadv2.

fs.read(fd[, options], callback)

Аналогично fs.read(), эта перегрузка принимает необязательный объект options. Если объект options не указан, используются значения по умолчанию, перечисленные выше.

fs.read(fd, buffer[, options], callback)

Аналогично fs.read(), эта перегрузка принимает необязательный объект options. Если объект options не указан, используются значения по умолчанию, перечисленные выше.

fs.readdir(path[, options], callback)

Читает содержимое каталога. Callback получает два аргумента (err, files), где files — это массив имён файлов каталога, исключая '.' и '..'.

Подробнее см. POSIX readdir(3).

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим кодировку имён файлов, передаваемых в callback. Если encoding установлено в 'buffer', возвращаемые имена файлов будут объектами Buffer.

Если options.withFileTypes установлено в true, массив files будет содержать объекты fs.Dirent.

fs.readFile(path[, options], callback)

Асинхронно читает всё содержимое файла.

1
2
3
4
5
6
import { readFile } from 'node:fs';

readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  console.log(data);
});

В callback передаются два аргумента (err, data), где data — содержимое файла.

Если кодировка не указана, возвращается исходный буфер.

Если options — строка, она задаёт кодировку:

1
2
3
import { readFile } from 'node:fs';

readFile('/etc/passwd', 'utf8', callback);

Если путь указывает на каталог, поведение fs.readFile() и fs.readFileSync() зависит от платформы. В macOS, Linux и Windows будет возвращена ошибка. В FreeBSD будет возвращено представление содержимого каталога.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { readFile } from 'node:fs';

// macOS, Linux, and Windows
readFile('<directory>', (err, data) => {
  // => [Error: EISDIR: illegal operation on a directory, read <directory>]
});

//  FreeBSD
readFile('<directory>', (err, data) => {
  // => null, <data>
});

Текущий запрос можно прервать с помощью AbortSignal. Если запрос прерван, callback вызывается с AbortError:

1
2
3
4
5
6
7
8
9
import { readFile } from 'node:fs';

const controller = new AbortController();
const signal = controller.signal;
readFile(fileInfo[0].name, { signal }, (err, buf) => {
  // ...
});
// When you want to abort the request
controller.abort();

Функция fs.readFile() буферизует весь файл целиком. Чтобы уменьшить расходы памяти, по возможности предпочтительнее использовать потоковое чтение через fs.createReadStream().

Прерывание выполняющегося запроса не отменяет отдельные запросы операционной системы, а лишь внутреннюю буферизацию, которую выполняет fs.readFile.

Файловые дескрипторы

  1. Any specified file descriptor has to support reading.
  2. If a file descriptor is specified as the path, it will not be closed automatically.
  3. The reading will begin at the current position. For example, if the file already had 'Hello World' and six bytes are read with the file descriptor, the call to fs.readFile() with the same file descriptor, would give 'World', rather than 'Hello World'.

Соображения производительности

Метод fs.readFile() асинхронно читает содержимое файла в память по одному фрагменту за раз, позволяя циклу событий выполняться между чтениями отдельных фрагментов. Благодаря этому операция чтения меньше влияет на другую активность, которая также может использовать базовый пул потоков libuv, но полное чтение файла в память занимает больше времени.

Дополнительные накладные расходы на чтение могут сильно различаться в разных системах и зависят от типа читаемого файла. Если файл не является обычным файлом (например, это канал) и Node.js не может определить его фактический размер, каждая операция чтения будет загружать по 64 КиБ данных. Для обычных файлов каждая операция чтения обрабатывает по 512 КиБ данных.

Для приложений, которым нужно максимально быстро читать содержимое файлов, лучше использовать fs.read() напрямую и самостоятельно управлять чтением всего содержимого файла на уровне кода приложения.

Issue Node.js #25741 содержит дополнительную информацию и подробный анализ производительности fs.readFile() для файлов разных размеров в разных версиях Node.js.

fs.readlink(path[, options], callback)

Читает содержимое символической ссылки, на которую указывает path. Callback получает два аргумента: (err, linkString).

Подробнее см. POSIX readlink(2).

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим кодировку символов для пути ссылки, передаваемого в callback. Если encoding установлено в 'buffer', возвращаемый путь ссылки будет передан как объект Buffer.

fs.readv(fd, buffers[, position], callback)

Читает данные из файла, указанного fd, и записывает их в массив ArrayBufferView с помощью readv().

position — это смещение от начала файла, с которого следует читать данные. Если typeof position !== 'number', данные будут читаться с текущей позиции.

Callback получает три аргумента: err, bytesRead и buffers. bytesRead показывает, сколько байтов было прочитано из файла.

Если этот метод вызывается в версии, полученной через util.promisify(), он возвращает промис для объекта со свойствами bytesRead и buffers.

fs.realpath(path[, options], callback)

Асинхронно вычисляет канонический путь, разрешая ., .. и символические ссылки.

Канонический путь не обязательно уникален. Жёсткие ссылки и bind mount могут предоставлять одну и ту же сущность файловой системы через разные пути.

Эта функция ведёт себя как realpath(3), за некоторыми исключениями:

  1. На файловых системах без учёта регистра преобразование регистра не выполняется.

  2. Максимальное число символических ссылок не зависит от платформы и обычно значительно больше, чем поддерживает нативная реализация realpath(3).

Callback получает два аргумента: (err, resolvedPath). Для разрешения относительных путей может использоваться process.cwd.

Поддерживаются только пути, которые можно преобразовать в строки UTF-8.

Необязательный аргумент options может быть строкой с именем кодировки или объектом со свойством encoding, задающим кодировку символов для пути, передаваемого в callback. Если encoding равен 'buffer', путь в callback передаётся как объект Buffer.

Если path разрешается в сокет или канал, функция вернёт системно-зависимое имя этого объекта.

Путь, который не существует, приводит к ошибке ENOENT. error.path содержит абсолютный путь к файлу.

fs.realpath.native(path[, options], callback)

Асинхронная версия realpath(3).

Callback получает два аргумента: (err, resolvedPath).

Поддерживаются только пути, которые можно преобразовать в строки UTF-8.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, определяющим кодировку символов для пути, передаваемого в callback. Если encoding равно 'buffer', возвращаемый путь будет передан как объект Buffer.

В Linux, когда Node.js слинкован с musl libc, для работы этой функции файловая система procfs должна быть смонтирована в /proc. У glibc этого ограничения нет.

fs.rename(oldPath, newPath, callback)

Асинхронно переименовывает файл из oldPath в путь, указанный как newPath. Если newPath уже существует, он будет перезаписан. Если по newPath находится каталог, вместо этого будет выброшена ошибка. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

См. также: rename(2).

1
2
3
4
5
6
import { rename } from 'node:fs';

rename('oldFile.txt', 'newFile.txt', (err) => {
  if (err) throw err;
  console.log('Rename complete!');
});

fs.rmdir(path[, options], callback)

  • path <string> | <Buffer> | <URL>
  • options <Object> в настоящий момент никаких опций не предоставляется. Раньше существовали опции recursive, maxBusyTries и emfileWait, но они были устаревшими и удалены. Аргумент options по-прежнему принимается для обратной совместимости, но не используется.
  • callback <Function>

Асинхронная версия rmdir(2). В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Использование fs.rmdir() для файла (а не каталога) приводит к ошибке ENOENT в Windows и ENOTDIR в POSIX.

Чтобы получить поведение, аналогичное Unix-команде rm -rf, используйте fs.rm() с опциями { recursive: true, force: true }.

fs.rm(path[, options], callback)

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • force <boolean> если true, исключения будут игнорироваться, если path не существует. По умолчанию: false.
    • maxRetries <integer> если возникает ошибка EBUSY, EMFILE, ENFILE, ENOTEMPTY или EPERM, Node.js повторяет операцию, линейно увеличивая ожидание на retryDelay миллисекунд при каждой попытке. Эта опция задаёт число повторов. Игнорируется, если recursive не равно true. По умолчанию: 0.
    • recursive <boolean> если true, выполняется рекурсивное удаление. В рекурсивном режиме операции повторяются при сбоях. По умолчанию: false.
    • retryDelay <integer> количество миллисекунд ожидания между повторными попытками. Игнорируется, если recursive не равно true. По умолчанию: 100.
  • callback <Function>

Асинхронно удаляет файлы и каталоги (по образцу стандартной POSIX-утилиты rm). В callback завершения не передаются никакие аргументы, кроме возможного исключения.

fs.stat(path[, options], callback)

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
    • throwIfNoEntry <boolean> следует ли выбрасывать исключение, если запись файловой системы не существует, вместо возврата undefined. По умолчанию: true.
  • callback <Function>

Асинхронная версия stat(2). Callback получает два аргумента (err, stats), где stats — объект fs.Stats.

В случае ошибки err.code будет одним из распространённых системных ошибок.

fs.stat() разыменовывает символические ссылки. Чтобы получить сведения о самих ссылках, используйте fs.lstat().

Использовать fs.stat() для проверки существования файла перед вызовом fs.open(), fs.readFile() или fs.writeFile() не рекомендуется. Вместо этого пользовательский код должен напрямую открывать/читать/записывать файл и обрабатывать возникающую ошибку, если файл недоступен.

Чтобы проверить существование файла без последующих операций с ним, рекомендуется fs.access().

Например, при следующей структуре каталогов:

1
2
3
- txtDir
-- file.txt
- app.js

Следующая программа проверит статистику для указанных путей:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { stat } from 'node:fs';

const pathsToCheck = ['./txtDir', './txtDir/file.txt'];

for (let i = 0; i < pathsToCheck.length; i++) {
  stat(pathsToCheck[i], (err, stats) => {
    console.log(stats.isDirectory());
    console.log(stats);
  });
}

Результирующий вывод будет примерно таким:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
true
Stats {
  dev: 16777220,
  mode: 16877,
  nlink: 3,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14214262,
  size: 96,
  blocks: 0,
  atimeMs: 1561174653071.963,
  mtimeMs: 1561174614583.3518,
  ctimeMs: 1561174626623.5366,
  birthtimeMs: 1561174126937.2893,
  atime: 2019-06-22T03:37:33.072Z,
  mtime: 2019-06-22T03:36:54.583Z,
  ctime: 2019-06-22T03:37:06.624Z,
  birthtime: 2019-06-22T03:28:46.937Z
}
false
Stats {
  dev: 16777220,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14214074,
  size: 8,
  blocks: 8,
  atimeMs: 1561174616618.8555,
  mtimeMs: 1561174614584,
  ctimeMs: 1561174614583.8145,
  birthtimeMs: 1561174007710.7478,
  atime: 2019-06-22T03:36:56.619Z,
  mtime: 2019-06-22T03:36:54.584Z,
  ctime: 2019-06-22T03:36:54.584Z,
  birthtime: 2019-06-22T03:26:47.711Z
}

fs.statfs(path[, options], callback)

Асинхронная версия statfs(2). Возвращает информацию о смонтированной файловой системе, содержащей path. Callback получает два аргумента (err, stats), где stats — объект fs.StatFs.

В случае ошибки err.code будет одним из распространённых системных ошибок.

fs.symlink(target, path[, type], callback)

Создаёт ссылку с именем path, указывающую на target. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

Подробнее см. POSIX symlink(2).

Аргумент type доступен только в Windows и игнорируется на других платформах. Он может принимать значения 'dir', 'file' или 'junction'. Если type равно null, Node.js автоматически определит тип target и использует 'file' или 'dir'. Если target не существует, будет использовано 'file'. Точки соединения Windows требуют, чтобы путь назначения был абсолютным. При использовании 'junction' аргумент target автоматически нормализуется к абсолютному пути. Точки соединения на томах NTFS могут указывать только на каталоги.

Относительные цели рассчитываются относительно родительского каталога ссылки.

1
2
3
import { symlink } from 'node:fs';

symlink('./mew', './mewtwo', callback);

Пример выше создаёт символическую ссылку mewtwo, указывающую на mew в том же каталоге:

1
2
3
4
$ tree .
.
├── mew
└── mewtwo -> ./mew

fs.truncate(path[, len], callback)

Усекает файл. В callback завершения не передаются никакие аргументы, кроме возможного исключения. В качестве первого аргумента также можно передать файловый дескриптор. В этом случае будет вызван fs.ftruncate().

1
2
3
4
5
6
import { truncate } from 'node:fs';
// Assuming that 'path/file.txt' is a regular file.
truncate('path/file.txt', (err) => {
  if (err) throw err;
  console.log('path/file.txt was truncated');
});
1
2
3
4
5
6
const { truncate } = require('node:fs');
// Assuming that 'path/file.txt' is a regular file.
truncate('path/file.txt', (err) => {
  if (err) throw err;
  console.log('path/file.txt was truncated');
});

Передача файлового дескриптора устарела и в будущем может приводить к выбрасыванию ошибки.

Подробнее см. POSIX truncate(2).

fs.unlink(path, callback)

Асинхронно удаляет файл или символическую ссылку. В callback завершения не передаются никакие аргументы, кроме возможного исключения.

1
2
3
4
5
6
import { unlink } from 'node:fs';
// Assuming that 'path/file.txt' is a regular file.
unlink('path/file.txt', (err) => {
  if (err) throw err;
  console.log('path/file.txt was deleted');
});

fs.unlink() не удаляет каталог — ни пустой, ни непустой. Чтобы удалить каталог, используйте fs.rmdir().

Подробнее см. POSIX unlink(2).

fs.unwatchFile(filename[, listener])

  • filename <string> | <Buffer> | <URL>
  • listener <Function> необязательный listener, ранее подключённый через fs.watchFile()

Прекращает отслеживание изменений для filename. Если указан listener, удаляется только этот конкретный listener. Иначе удаляются все listeners, что фактически останавливает наблюдение за filename.

Вызов fs.unwatchFile() с именем файла, который не отслеживается, ничего не делает и не считается ошибкой.

Использование fs.watch() эффективнее, чем fs.watchFile() и fs.unwatchFile(). По возможности вместо fs.watchFile() и fs.unwatchFile() следует использовать fs.watch().

fs.utimes(path, atime, mtime, callback)

Изменяет временные метки файловой системы объекта, на который указывает path.

Аргументы atime и mtime подчиняются следующим правилам:

  • значения могут быть числами, представляющими Unix-время в секундах, объектами Date или числовой строкой вроде '123456789.0';
  • если значение нельзя преобразовать в число либо оно равно NaN, Infinity или -Infinity, будет выброшена ошибка Error.

fs.watch(filename[, options][, listener])

  • filename <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • persistent <boolean> указывает, должен ли процесс продолжать работу, пока файлы отслеживаются. По умолчанию: true.
    • recursive <boolean> указывает, нужно ли отслеживать все подкаталоги или только текущий каталог. Применяется, когда указан каталог, и только на поддерживаемых платформах (см. Предостережения). По умолчанию: false.
    • encoding <string> задаёт кодировку символов для имени файла, передаваемого в listener. По умолчанию: 'utf8'.
    • signal <AbortSignal> позволяет закрыть наблюдатель с помощью AbortSignal.
    • throwIfNoEntry <boolean> указывает, следует ли выбрасывать исключение, если путь не существует. По умолчанию: true.
    • ignore <string> | <RegExp> | <Function> | <Array> шаблон(ы) для игнорирования. Строки трактуются как glob-шаблоны (с использованием minimatch), шаблоны RegExp проверяются по имени файла, а функции получают имя файла и возвращают true, если его нужно игнорировать. По умолчанию: undefined.
  • listener <Function> | undefined По умолчанию: undefined
  • Возвращает: <fs.FSWatcher>

Отслеживает изменения для filename, где filename может быть либо файлом, либо каталогом.

Второй аргумент необязателен. Если options передан как строка, он задаёт encoding. В противном случае options следует передавать как объект.

Callback listener получает два аргумента (eventType, filename). eventType принимает значение 'rename' или 'change', а filename — это имя файла, вызвавшего событие.

На большинстве платформ событие 'rename' генерируется всякий раз, когда имя файла появляется или исчезает в каталоге.

Callback-слушатель привязан к событию 'change', которое генерирует fs.FSWatcher, но это не то же самое, что значение 'change' у eventType.

Если передан signal, вызов abort() у соответствующего AbortController закроет возвращённый fs.FSWatcher.

Предостережения

API fs.watch не является полностью одинаковым на всех платформах и в некоторых ситуациях недоступно.

В Windows никакие события не будут сгенерированы, если отслеживаемый каталог был перемещён или переименован. При удалении отслеживаемого каталога сообщается об ошибке EPERM.

API fs.watch не обеспечивает никакой защиты от злонамеренных действий в файловой системе. Например, в Windows оно реализовано как мониторинг изменений в каталоге, а не в конкретных файлах. Из-за этого файл можно подменить, и fs будет сообщать об изменениях уже в новом файле с тем же именем.

Доступность

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

  • В Linux используется inotify(7).
  • В BSD используется kqueue(2).
  • В macOS для файлов используется kqueue(2), а для каталогов — FSEvents.
  • В SunOS (включая Solaris и SmartOS) используются event ports.
  • В Windows эта возможность зависит от ReadDirectoryChangesW.
  • В AIX эта возможность зависит от AHAFS, который должен быть включён.
  • В IBM i эта возможность не поддерживается.

Если по какой-либо причине базовая функциональность недоступна, fs.watch() не сможет работать и может выбросить исключение. Например, наблюдение за файлами или каталогами может быть ненадёжным, а в некоторых случаях невозможным, в сетевых файловых системах (NFS, SMB и т. п.) или в файловых системах хоста при использовании ПО виртуализации вроде Vagrant или Docker.

По-прежнему можно использовать fs.watchFile(), который применяет опрос через stat, но этот метод медленнее и менее надёжен.

Inode

В Linux и macOS fs.watch() разрешает путь до inode и отслеживает именно inode. Если отслеживаемый путь удалить и создать заново, ему будет назначен новый inode. Наблюдатель сгенерирует событие удаления, но продолжит следить за исходным inode. События для нового inode сгенерированы не будут. Это ожидаемое поведение.

В AIX файлы сохраняют один и тот же inode на всём протяжении своего существования. Сохранение и закрытие отслеживаемого файла в AIX приведёт к двум уведомлениям: одному о добавлении нового содержимого и одному об усечении.

Аргумент filename

Передача аргумента filename в callback поддерживается только в Linux, macOS, Windows и AIX. Даже на поддерживаемых платформах наличие filename не гарантируется. Поэтому не следует предполагать, что аргумент filename всегда будет передан в callback; предусмотрите запасную логику на случай, если он равен null.

1
2
3
4
5
6
7
8
9
import { watch } from 'node:fs';
watch('somedir', (eventType, filename) => {
  console.log(`event type is: ${eventType}`);
  if (filename) {
    console.log(`filename provided: ${filename}`);
  } else {
    console.log('filename not provided');
  }
});

fs.watchFile(filename[, options], listener)

Отслеживает изменения для filename. Callback listener будет вызываться каждый раз, когда к файлу происходит доступ.

Аргумент options можно опустить. Если он указан, это должен быть объект. Объект options может содержать булево свойство persistent, указывающее, должен ли процесс продолжать работу, пока файлы отслеживаются. Объект options также может задавать свойство interval, определяющее частоту опроса цели в миллисекундах.

listener получает два аргумента: текущий объект stat и предыдущий объект stat:

1
2
3
4
5
6
import { watchFile } from 'node:fs';

watchFile('message.text', (curr, prev) => {
  console.log(`the current mtime is: ${curr.mtime}`);
  console.log(`the previous mtime was: ${prev.mtime}`);
});

Эти объекты stat являются экземплярами fs.Stat. Если опция bigint равна true, числовые значения в этих объектах представлены как BigInt.

Чтобы получать уведомление именно об изменении файла, а не только о доступе к нему, необходимо сравнивать curr.mtimeMs и prev.mtimeMs.

Когда операция fs.watchFile приводит к ошибке ENOENT, listener будет вызван один раз, при этом все поля будут обнулены (а для дат будет использована Unix Epoch). Если файл позже будет создан, listener будет вызван снова, уже с актуальными объектами stat. Это изменение поведения, действующее с v0.10.

Использование fs.watch() эффективнее, чем fs.watchFile и fs.unwatchFile. По возможности вместо fs.watchFile и fs.unwatchFile следует использовать fs.watch.

Когда файл, отслеживаемый через fs.watchFile(), исчезает и затем появляется снова, содержимое previous во втором событии callback (повторное появление файла) будет таким же, как содержимое previous в первом событии callback (его исчезновение).

Это происходит, когда:

  • файл удаляется, а затем восстанавливается;
  • файл переименовывается, а затем переименовывается ещё раз обратно в исходное имя.

fs.write(fd, buffer, offset[, length[, position]], callback)

Записывает buffer в файл, указанный файловым дескриптором fd.

offset определяет часть буфера, которая будет записана, а length — это целое число, задающее количество байтов для записи.

position указывает смещение от начала файла, куда следует записать эти данные. Если typeof position !== 'number', данные будут записаны по текущей позиции. См. pwrite(2).

Callback получает три аргумента (err, bytesWritten, buffer), где bytesWritten указывает, сколько байтов было записано из buffer.

Если этот метод вызывается в версии, полученной через util.promisify(), он возвращает промис для объекта со свойствами bytesWritten и buffer.

Небезопасно использовать fs.write() несколько раз для одного и того же файла, не дожидаясь callback. Для такого сценария рекомендуется fs.createWriteStream().

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

fs.write(fd, buffer[, options], callback)

Записывает buffer в файл, указанный файловым дескриптором fd.

Подобно приведённой выше функции fs.write, эта версия принимает необязательный объект options. Если options не указан, будут использованы значения по умолчанию, перечисленные выше.

fs.write(fd, string[, position[, encoding]], callback)

Записывает string в файл, указанный файловым дескриптором fd. Если string не является строкой, будет выброшено исключение.

position указывает смещение от начала файла, куда следует записать эти данные. Если typeof position !== 'number', данные будут записаны по текущей позиции. См. pwrite(2).

encoding — ожидаемая кодировка строки.

Callback получает аргументы (err, written, string), где written указывает, сколько байтов потребовалось для записи переданной строки. Количество записанных байтов не обязательно совпадает с количеством записанных символов строки. См. Buffer.byteLength.

Небезопасно вызывать fs.write() несколько раз для одного и того же файла, не дожидаясь обратного вызова. Для такого сценария рекомендуется fs.createWriteStream().

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

В Windows, если файловый дескриптор подключён к консоли (например, fd == 1 или stdout), строка, содержащая не-ASCII-символы, по умолчанию не будет корректно отображаться независимо от используемой кодировки. Консоль можно настроить на корректное отображение UTF-8, изменив активную кодовую страницу командой chcp 65001. Подробнее см. в документации chcp.

fs.writeFile(file, data[, options], callback)

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

Когда file — это файловый дескриптор, поведение аналогично прямому вызову fs.write() (что и рекомендуется). См. примечания ниже об использовании файлового дескриптора.

Опция encoding игнорируется, если data является буфером.

Опция mode влияет только на вновь создаваемый файл. Подробнее см. fs.open().

1
2
3
4
5
6
7
8
import { writeFile } from 'node:fs';
import { Buffer } from 'node:buffer';

const data = new Uint8Array(Buffer.from('Hello Node.js'));
writeFile('message.txt', data, (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

Если options — строка, она задаёт кодировку:

1
2
3
import { writeFile } from 'node:fs';

writeFile('message.txt', 'Hello Node.js', 'utf8', callback);

Небезопасно использовать fs.writeFile() несколько раз для одного и того же файла, не дожидаясь callback. Для такого сценария рекомендуется fs.createWriteStream().

Как и fs.readFile, fs.writeFile — это удобный метод, который внутри выполняет несколько вызовов write, чтобы записать переданный буфер. Для кода, чувствительного к производительности, стоит рассмотреть fs.createWriteStream().

Можно использовать AbortSignal, чтобы отменить fs.writeFile(). Отмена выполняется по принципу "best effort", и некоторое количество данных, вероятно, всё равно будет записано.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { writeFile } from 'node:fs';
import { Buffer } from 'node:buffer';

const controller = new AbortController();
const { signal } = controller;
const data = new Uint8Array(Buffer.from('Hello Node.js'));
writeFile('message.txt', data, { signal }, (err) => {
  // When a request is aborted - the callback is called with an AbortError
});
// When the request should be aborted
controller.abort();

Прерывание выполняющегося запроса не отменяет отдельные запросы операционной системы, а лишь внутреннюю буферизацию, которую выполняет fs.writeFile.

Использование fs.writeFile() с файловыми дескрипторами

Когда file является файловым дескриптором, поведение почти идентично прямому вызову fs.write(), например:

1
2
3
4
import { write } from 'node:fs';
import { Buffer } from 'node:buffer';

write(fd, Buffer.from(data, options.encoding), callback);

Отличие от прямого вызова fs.write() состоит в том, что при некоторых необычных условиях fs.write() может записать только часть буфера, и для записи оставшихся данных потребуется повторный вызов, тогда как fs.writeFile() повторяет запись, пока данные не будут записаны полностью (или пока не произойдёт ошибка).

Следствия этого часто вызывают путаницу. В случае файлового дескриптора файл не заменяется! Данные не обязательно записываются в начало файла, и исходные данные файла могут остаться до и/или после вновь записанных данных.

Например, если fs.writeFile() вызвать два раза подряд, сначала записав строку 'Hello', а затем строку ', World', файл будет содержать 'Hello, World' и, возможно, часть исходных данных файла (в зависимости от размера исходного файла и позиции файлового дескриптора). Если бы вместо дескриптора использовалось имя файла, гарантировалось бы, что файл содержит только ', World'.

fs.writev(fd, buffers[, position], callback)

Записывает массив ArrayBufferView в файл, указанный файловым дескриптором fd, с помощью writev().

position — это смещение от начала файла, куда следует записать эти данные. Если typeof position !== 'number', данные будут записаны по текущей позиции.

Callback получит три аргумента: err, bytesWritten и buffers. bytesWritten показывает, сколько байт было записано из buffers.

Если этот метод обёрнут через util.promisify(), он возвращает промис для объекта со свойствами bytesWritten и buffers.

Небезопасно использовать fs.writev() несколько раз для одного и того же файла, не дожидаясь callback. Для такого сценария используйте fs.createWriteStream().

В Linux позиционная запись не работает, если файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

Synchronous API

Синхронные API выполняют все операции синхронно, блокируя цикл событий до тех пор, пока операция не завершится успешно или с ошибкой.

fs.accessSync(path[, mode])

Синхронно проверяет права пользователя для файла или каталога, указанных в path. Аргумент mode — необязательное целое число, задающее выполняемые проверки доступности. mode должен быть либо значением fs.constants.F_OK, либо маской, составленной через побитовое OR из fs.constants.R_OK, fs.constants.W_OK и fs.constants.X_OK (например, fs.constants.W_OK | fs.constants.R_OK). Возможные значения mode см. в разделе Константы доступа к файлам.

Если любая из проверок доступности не проходит, будет выброшен Error. Иначе метод вернёт undefined.

1
2
3
4
5
6
7
8
import { accessSync, constants } from 'node:fs';

try {
  accessSync('etc/passwd', constants.R_OK | constants.W_OK);
  console.log('can read/write');
} catch (err) {
  console.error('no access!');
}

fs.appendFileSync(path, data[, options])

Синхронно дописывает данные в файл; при отсутствии файла создаёт его. data может быть строкой или Buffer.

Опция mode влияет только на вновь создаваемый файл. Подробнее см. fs.open().

1
2
3
4
5
6
7
8
import { appendFileSync } from 'node:fs';

try {
  appendFileSync('message.txt', 'data to append');
  console.log('The "data to append" was appended to file!');
} catch (err) {
  /* Handle the error */
}

Если options — строка, она задаёт кодировку:

1
2
3
import { appendFileSync } from 'node:fs';

appendFileSync('message.txt', 'data to append', 'utf8');

path может быть задан как числовой файловый дескриптор, открытый для добавления (через fs.open() или fs.openSync()). Файловый дескриптор не будет закрыт автоматически.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { openSync, closeSync, appendFileSync } from 'node:fs';

let fd;

try {
  fd = openSync('message.txt', 'a');
  appendFileSync(fd, 'data to append', 'utf8');
} catch (err) {
  /* Handle the error */
} finally {
  if (fd !== undefined)
    closeSync(fd);
}

fs.chmodSync(path, mode)

Подробности см. в документации асинхронной версии этого API: fs.chmod().

Подробнее см. POSIX chmod(2).

fs.chownSync(path, uid, gid)

Синхронно изменяет владельца и группу файла. Возвращает undefined. Это синхронная версия fs.chown().

Подробнее см. POSIX chown(2).

fs.closeSync(fd)

Закрывает файловый дескриптор. Возвращает undefined.

Вызов fs.closeSync() для любого файлового дескриптора (fd), который в данный момент используется другой операцией fs, может привести к неопределённому поведению.

Подробнее см. POSIX close(2).

fs.copyFileSync(src, dest[, mode])

  • src <string> | <Buffer> | <URL> имя исходного файла для копирования
  • dest <string> | <Buffer> | <URL> имя целевого файла операции копирования
  • mode <integer> модификаторы операции копирования. По умолчанию: 0.

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

mode — необязательное целое число, задающее поведение операции копирования. Можно создать маску из двух или более значений, объединённых побитовым ИЛИ (например, fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

  • fs.constants.COPYFILE_EXCL: операция копирования завершится ошибкой, если dest уже существует.
  • fs.constants.COPYFILE_FICLONE: операция копирования попытается создать reflink с копированием по записи. Если платформа не поддерживает copy-on-write, используется запасной механизм копирования.
  • fs.constants.COPYFILE_FICLONE_FORCE: операция копирования попытается создать reflink с копированием по записи. Если платформа не поддерживает copy-on-write, операция завершится ошибкой.
1
2
3
4
5
6
7
8
import { copyFileSync, constants } from 'node:fs';

// destination.txt will be created or overwritten by default.
copyFileSync('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');

// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);

fs.cpSync(src, dest[, options])

  • src <string> | <URL> Исходный путь для копирования.
  • dest <string> | <URL> Путь назначения для копирования.
  • options <Object>
    • dereference <boolean> Разыменовывать символические ссылки. По умолчанию: false.
    • errorOnExist <boolean> Если force равно false и место назначения существует, выбрасывать ошибку. По умолчанию: false.
    • filter <Function> Функция для фильтрации копируемых файлов и каталогов. Верните true, чтобы скопировать элемент, и false, чтобы его проигнорировать. Если игнорируется каталог, всё его содержимое также будет пропущено. По умолчанию: undefined.
      • src <string> Исходный путь для копирования.
      • dest <string> Путь назначения для копирования.
      • Возвращает: <boolean> Любое значение (не Promise), приводимое к boolean.
    • force <boolean> Перезаписывать существующий файл или каталог. Операция копирования будет игнорировать ошибки, если установить false, а место назначения уже существует. Используйте опцию errorOnExist, чтобы изменить это поведение. По умолчанию: true.
    • mode <integer> Модификаторы операции копирования. По умолчанию: 0. См. флаг mode у fs.copyFileSync().
    • preserveTimestamps <boolean> Если true, временные метки из src будут сохранены. По умолчанию: false.
    • recursive <boolean> Копировать каталоги рекурсивно. По умолчанию: false
    • verbatimSymlinks <boolean> Если true, разрешение путей для символических ссылок будет пропущено. По умолчанию: false

Синхронно копирует всю структуру каталогов из src в dest, включая подкаталоги и файлы.

При копировании каталога в другой каталог glob-шаблоны не поддерживаются, а поведение аналогично cp dir1/ dir2/.

fs.existsSync(path)

Возвращает true, если путь существует, и false в противном случае.

Подробнее см. документацию асинхронного варианта этого API: fs.exists().

Метод fs.exists() устарел, а fs.existsSync() — нет. У fs.exists() параметр callback имеет сигнатуру, не согласованную с другими callback'ами Node.js. fs.existsSync() callback не использует.

1
2
3
4
import { existsSync } from 'node:fs';

if (existsSync('/etc/passwd'))
  console.log('The path exists.');

fs.fchmodSync(fd, mode)

Устанавливает права доступа к файлу. Возвращает undefined.

Подробнее см. POSIX fchmod(2).

fs.fchownSync(fd, uid, gid)

  • fd <integer>
  • uid <integer> идентификатор пользователя (UID) нового владельца файла.
  • gid <integer> идентификатор группы (GID) новой группы файла.

Устанавливает владельца файла. Возвращает undefined.

Подробнее см. POSIX fchown(2).

fs.fdatasyncSync(fd)

Принудительно переводит все текущие поставленные в очередь операции ввода-вывода, связанные с файлом, в состояние синхронизированного завершения ввода-вывода на уровне операционной системы. Подробнее см. документацию POSIX fdatasync(2). Возвращает undefined.

fs.fstatSync(fd[, options])

  • fd <integer>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
  • Возвращает: <fs.Stats>

Получает fs.Stats для файлового дескриптора.

Подробнее см. POSIX fstat(2).

fs.fsyncSync(fd)

Запрашивает сброс всех данных открытого файлового дескриптора на устройство хранения. Конкретная реализация зависит от операционной системы и устройства. Подробнее см. документацию POSIX fsync(2). Возвращает undefined.

fs.ftruncateSync(fd[, len])

Усекает файловый дескриптор. Возвращает undefined.

Подробнее см. документацию асинхронного варианта этого API: fs.ftruncate().

fs.futimesSync(fd, atime, mtime)

Синхронный вариант fs.futimes(). Возвращает undefined.

fs.globSync(pattern[, options])

  • pattern <string> | <string[]>
  • options <Object>
    • cwd <string> | <URL> Текущий рабочий каталог. По умолчанию: process.cwd()
    • exclude <Function> | <string[]> Функция для исключения файлов и каталогов из выборки либо список glob-шаблонов для исключения. Если передана функция, верните true, чтобы исключить элемент, и false, чтобы его включить. По умолчанию: undefined. Если передан массив строк, каждая строка должна быть glob-шаблоном, задающим исключаемые пути. Примечание: шаблоны с отрицанием (например, '!foo.js') не поддерживаются.
    • withFileTypes <boolean> Если true, glob возвращает пути в виде объектов Dirent; если false — в виде строк. По умолчанию: false.
  • Возвращает: <string[]> пути к файлам, соответствующим шаблону.
1
2
3
import { globSync } from 'node:fs';

console.log(globSync('**/*.js'));
1
2
3
const { globSync } = require('node:fs');

console.log(globSync('**/*.js'));

fs.lchmodSync(path, mode)

Стабильность: 0 - устарело или набрало много негативных отзывов

Изменяет права доступа символической ссылки. Возвращает undefined.

Этот метод реализован только в macOS.

Подробнее см. POSIX lchmod(2).

fs.lchownSync(path, uid, gid)

  • path <string> | <Buffer> | <URL>
  • uid <integer> идентификатор пользователя (UID) нового владельца файла.
  • gid <integer> идентификатор группы (GID) новой группы файла.

Устанавливает владельца для пути. Возвращает undefined.

Подробнее см. POSIX lchown(2).

fs.lutimesSync(path, atime, mtime)

Изменяет временные метки файловой системы для символической ссылки, на которую указывает path. Возвращает undefined либо выбрасывает исключение при неверных параметрах или сбое операции. Это синхронный вариант fs.lutimes().

fs.linkSync(existingPath, newPath)

Создаёт новую жёсткую ссылку с existingPath на newPath. Подробнее см. POSIX link(2). Возвращает undefined.

fs.lstatSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
    • throwIfNoEntry <boolean> следует ли выбрасывать исключение, если запись файловой системы не существует, вместо возврата undefined. По умолчанию: true.
  • Возвращает: <fs.Stats>

Получает fs.Stats для символической ссылки, на которую указывает path.

Подробнее см. POSIX lstat(2).

fs.mkdirSync(path[, options])

Синхронно создаёт каталог. Возвращает undefined, либо, если recursive равно true, путь к первому созданному каталогу. Это синхронная версия fs.mkdir().

Подробнее см. POSIX mkdir(2).

fs.mkdtempSync(prefix[, options])

Возвращает путь к созданному каталогу.

Подробнее см. документацию асинхронного варианта этого API: fs.mkdtemp().

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим используемую кодировку символов.

fs.mkdtempDisposableSync(prefix[, options])

Возвращает disposable-объект, чьё свойство path содержит путь к созданному каталогу. Когда объект освобождается, каталог и его содержимое будут удалены, если они всё ещё существуют. Если каталог не удаётся удалить, освобождение выбросит ошибку. У объекта есть метод remove(), выполняющий ту же задачу.

Подробнее см. документацию fs.mkdtemp().

Версии этого API с callback нет, потому что он разработан для использования с синтаксисом using.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, задающим используемую кодировку символов.

fs.opendirSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • encoding <string> | null По умолчанию: 'utf8'
    • bufferSize <number> число записей каталога, внутренне буферизуемых при чтении. Более высокие значения улучшают производительность, но увеличивают потребление памяти. По умолчанию: 32
    • recursive <boolean> По умолчанию: false
  • Возвращает: <fs.Dir>

Синхронно открывает каталог. См. opendir(3).

Создаёт fs.Dir, содержащий все последующие функции для чтения из каталога и его очистки.

Опция encoding задаёт кодировку для path при открытии каталога и последующих операциях чтения.

fs.openSync(path[, flags[, mode]])

Возвращает целое число, представляющее файловый дескриптор.

Подробнее см. документацию асинхронного варианта этого API: fs.open().

fs.readdirSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <string> | <Object>
    • encoding <string> По умолчанию: 'utf8'
    • withFileTypes <boolean> По умолчанию: false
    • recursive <boolean> если true, читает содержимое каталога рекурсивно. В рекурсивном режиме будут перечислены все файлы, вложенные файлы и каталоги. По умолчанию: false.
  • Возвращает: <string[]> | <Buffer[]> | <fs.Dirent[]>

Читает содержимое каталога.

Подробнее см. POSIX readdir(3).

Необязательный аргумент options может быть строкой с именем кодировки или объектом со свойством encoding, задающим кодировку имён возвращаемых файлов. Если encoding равен 'buffer', имена возвращаются как объекты Buffer.

Если options.withFileTypes равен true, в результате будут объекты fs.Dirent.

fs.readFileSync(path[, options])

Возвращает содержимое path.

Подробнее см. документацию асинхронного варианта этого API: fs.readFile().

Если указана опция encoding, эта функция возвращает строку. В противном случае она возвращает буфер.

Аналогично fs.readFile(): если path — каталог, поведение fs.readFileSync() зависит от платформы.

1
2
3
4
5
6
7
8
import { readFileSync } from 'node:fs';

// macOS, Linux, and Windows
readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]

//  FreeBSD
readFileSync('<directory>'); // => <data>

fs.readlinkSync(path[, options])

Возвращает строковое значение символической ссылки.

Подробнее см. POSIX readlink(2).

Необязательный аргумент options может быть строкой с именем кодировки или объектом со свойством encoding, задающим кодировку символов для возвращаемого пути ссылки. Если encoding равен 'buffer', путь возвращается как объект Buffer.

fs.readSync(fd, buffer, offset, length[, position])

Возвращает количество bytesRead.

Подробнее см. документацию асинхронного варианта этого API: fs.read().

fs.readSync(fd, buffer[, options])

Возвращает количество bytesRead.

Подобно приведённой выше функции fs.readSync, эта версия принимает необязательный объект options. Если options не указан, будут использованы значения по умолчанию, перечисленные выше.

Подробнее см. документацию асинхронного варианта этого API: fs.read().

fs.readvSync(fd, buffers[, position])

Подробнее см. документацию асинхронного варианта этого API: fs.readv().

fs.realpathSync(path[, options])

Возвращает разрешённый путь.

Подробнее см. документацию асинхронного варианта этого API: fs.realpath().

fs.realpathSync.native(path[, options])

Синхронная версия realpath(3).

Поддерживаются только пути, которые можно преобразовать в строки UTF-8.

Необязательный аргумент options может быть строкой, задающей кодировку, либо объектом со свойством encoding, определяющим кодировку символов для возвращаемого пути. Если encoding равно 'buffer', возвращаемый путь будет передан как объект Buffer.

В Linux, когда Node.js слинкован с musl libc, для работы этой функции файловая система procfs должна быть смонтирована в /proc. У glibc этого ограничения нет.

fs.renameSync(oldPath, newPath)

Переименовывает файл из oldPath в newPath. Возвращает undefined.

Подробнее см. POSIX rename(2).

fs.rmdirSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object> в настоящий момент никаких опций не предоставляется. Раньше существовали опции recursive, maxBusyTries и emfileWait, но они были устаревшими и удалены. Аргумент options по-прежнему принимается для обратной совместимости, но не используется.

Синхронная версия rmdir(2). Возвращает undefined.

Использование fs.rmdirSync() для файла (а не каталога) приводит к ошибке ENOENT в Windows и ENOTDIR в POSIX.

Чтобы получить поведение, близкое к команде Unix rm -rf, используйте fs.rmSync() с опциями { recursive: true, force: true }.

fs.rmSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • force <boolean> если true, исключения будут игнорироваться, если path не существует. По умолчанию: false.
    • maxRetries <integer> если возникает ошибка EBUSY, EMFILE, ENFILE, ENOTEMPTY или EPERM, Node.js повторяет операцию, линейно увеличивая ожидание на retryDelay миллисекунд при каждой попытке. Эта опция задаёт число повторов. Игнорируется, если recursive не равно true. По умолчанию: 0.
    • recursive <boolean> если true, выполняется рекурсивное удаление каталога. В рекурсивном режиме операции повторяются при сбоях. По умолчанию: false.
    • retryDelay <integer> количество миллисекунд ожидания между повторными попытками. Игнорируется, если recursive не равно true. По умолчанию: 100.

Синхронно удаляет файлы и каталоги (по образцу стандартной POSIX-утилиты rm). Возвращает undefined.

fs.statSync(path[, options])

  • path <string> | <Buffer> | <URL>
  • options <Object>
    • bigint <boolean> должны ли числовые значения в возвращаемом объекте fs.Stats иметь тип bigint. По умолчанию: false.
    • throwIfNoEntry <boolean> следует ли выбрасывать исключение, если запись файловой системы не существует, вместо возврата undefined. По умолчанию: true.
  • Возвращает: <fs.Stats>

Получает fs.Stats для указанного пути.

fs.statfsSync(path[, options])

Синхронная версия statfs(2). Возвращает информацию о смонтированной файловой системе, содержащей path.

В случае ошибки err.code будет одним из распространённых системных ошибок.

fs.symlinkSync(target, path[, type])

Подробнее см. документацию асинхронного варианта этого API: fs.symlink().

fs.truncateSync(path[, len])

Усекает файл. Возвращает undefined. В качестве первого аргумента также можно передать файловый дескриптор. В этом случае будет вызван fs.ftruncateSync().

Передача файлового дескриптора устарела и в будущем может приводить к выбрасыванию ошибки.

fs.unlinkSync(path)

Синхронная версия unlink(2). Возвращает undefined.

fs.utimesSync(path, atime, mtime)

Подробнее см. документацию асинхронного варианта этого API: fs.utimes().

fs.writeFileSync(file, data[, options])

Опция mode влияет только на вновь создаваемый файл. Подробнее см. fs.open().

Подробнее см. документацию асинхронного варианта этого API: fs.writeFile().

fs.writeSync(fd, buffer, offset[, length[, position]])

Подробнее см. документацию асинхронного варианта этого API: fs.write(fd, buffer...).

fs.writeSync(fd, buffer[, options])

Подробнее см. документацию асинхронного варианта этого API: fs.write(fd, buffer...).

fs.writeSync(fd, string[, position[, encoding]])

  • fd <integer>
  • string <string>
  • position <integer> | null По умолчанию: null
  • encoding <string> По умолчанию: 'utf8'
  • Возвращает: <number> Количество записанных байт.

Подробнее см. документацию асинхронного варианта этого API: fs.write(fd, string...).

fs.writevSync(fd, buffers[, position])

Подробнее см. документацию асинхронного варианта этого API: fs.writev().

Общие объекты

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

Класс: fs.Dir

Класс, представляющий поток каталога.

Создаётся методами fs.opendir(), fs.opendirSync() или fsPromises.opendir().

1
2
3
4
5
6
7
8
9
import { opendir } from 'node:fs/promises';

try {
  const dir = await opendir('./');
  for await (const dirent of dir)
    console.log(dirent.name);
} catch (err) {
  console.error(err);
}

При использовании асинхронного итератора объект fs.Dir будет автоматически закрыт после завершения итерации.

dir.close()

Асинхронно закрывает базовый дескриптор ресурса каталога. Последующие чтения приведут к ошибкам.

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

dir.close(callback)

Асинхронно закрывает базовый дескриптор ресурса каталога. Последующие чтения приведут к ошибкам.

callback будет вызван после закрытия дескриптора ресурса.

dir.closeSync()

Синхронно закрывает базовый дескриптор ресурса каталога. Последующие чтения приведут к ошибкам.

dir.path

Путь к этому каталогу только для чтения, переданный в fs.opendir(), fs.opendirSync() или fsPromises.opendir().

dir.read()

  • Возвращает: <Promise>, который выполняется с fs.Dirent или null

Асинхронно читает следующую запись каталога через readdir(3) как fs.Dirent.

Возвращает промис, который будет выполнен с fs.Dirent или null, если больше нет записей каталога для чтения.

Записи каталога, возвращаемые этой функцией, не имеют определённого порядка и зависят от базовых механизмов каталогов операционной системы. Записи, добавленные или удалённые во время итерации по каталогу, могут не попасть в результаты итерации.

dir.read(callback)

Асинхронно читает следующую запись каталога через readdir(3) как fs.Dirent.

После завершения чтения callback будет вызван с fs.Dirent или null, если больше нет записей каталога для чтения.

Записи каталога, возвращаемые этой функцией, не имеют определённого порядка и зависят от базовых механизмов каталогов операционной системы. Записи, добавленные или удалённые во время итерации по каталогу, могут не попасть в результаты итерации.

dir.readSync()

Синхронно читает следующую запись каталога как fs.Dirent. Подробнее см. документацию POSIX readdir(3).

Если больше нет записей каталога для чтения, будет возвращён null.

Записи каталога, возвращаемые этой функцией, не имеют определённого порядка и зависят от базовых механизмов каталогов операционной системы. Записи, добавленные или удалённые во время итерации по каталогу, могут не попасть в результаты итерации.

dir[Symbol.asyncIterator]()

Асинхронно перебирает каталог, пока не будут прочитаны все записи. Подробнее см. документацию POSIX readdir(3).

Записи, возвращаемые асинхронным итератором, всегда являются fs.Dirent. Случай null из dir.read() обрабатывается внутри.

Пример см. в разделе fs.Dir.

Записи каталога, возвращаемые этим итератором, не имеют определённого порядка и зависят от базовых механизмов каталогов операционной системы. Записи, добавленные или удалённые во время итерации по каталогу, могут не попасть в результаты итерации.

dir[Symbol.asyncDispose]()

Вызывает dir.close(), если дескриптор каталога открыт, и возвращает промис, который выполняется после завершения освобождения ресурса.

dir[Symbol.dispose]()

Вызывает dir.closeSync(), если дескриптор каталога открыт, и возвращает undefined.

Класс: fs.Dirent

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

Кроме того, когда fs.readdir() или fs.readdirSync() вызываются с опцией withFileTypes, установленной в true, результирующий массив заполняется объектами fs.Dirent, а не строками или Buffer.

dirent.isBlockDevice()

Возвращает true, если объект fs.Dirent описывает блочное устройство.

dirent.isCharacterDevice()

Возвращает true, если объект fs.Dirent описывает символьное устройство.

dirent.isDirectory()

Возвращает true, если объект fs.Dirent описывает каталог файловой системы.

dirent.isFIFO()

Возвращает true, если объект fs.Dirent описывает канал FIFO (first-in-first-out).

dirent.isFile()

Возвращает true, если объект fs.Dirent описывает обычный файл.

dirent.isSocket()

Возвращает true, если объект fs.Dirent описывает сокет.

Возвращает true, если объект fs.Dirent описывает символическую ссылку.

dirent.name

Имя файла, на который указывает этот объект fs.Dirent. Тип этого значения определяется options.encoding, переданным в fs.readdir() или fs.readdirSync().

dirent.parentPath

Путь к родительскому каталогу файла, на который указывает этот объект fs.Dirent.

Класс: fs.FSWatcher

Успешный вызов метода fs.watch() возвращает новый объект fs.FSWatcher.

Все объекты fs.FSWatcher генерируют событие 'change' всякий раз, когда изменяется конкретный отслеживаемый файл.

Событие: 'change'

  • eventType <string> тип произошедшего события изменения
  • filename <string> | <Buffer> имя изменившегося файла (если применимо/доступно)

Генерируется, когда что-то изменяется в отслеживаемом каталоге или файле. Подробнее см. в fs.watch().

Аргумент filename может отсутствовать в зависимости от поддержки со стороны операционной системы. Если filename передан, он будет иметь тип Buffer, если fs.watch() вызван с опцией encoding, установленной в 'buffer', иначе filename будет строкой UTF-8.

1
2
3
4
5
6
7
8
import { watch } from 'node:fs';
// Пример обработки через слушатель fs.watch()
watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
  if (filename) {
    console.log(filename);
    // Выведет: <Buffer ...>
  }
});

Событие: 'close'

Генерируется, когда наблюдатель прекращает следить за изменениями. Закрытый объект fs.FSWatcher больше нельзя использовать в обработчике события.

Событие: 'error'

Генерируется при возникновении ошибки во время наблюдения за файлом. Объект fs.FSWatcher, для которого произошла ошибка, больше нельзя использовать в обработчике события.

watcher.close()

Прекращает наблюдение за изменениями для данного fs.FSWatcher. После остановки объект fs.FSWatcher больше нельзя использовать.

watcher.ref()

При вызове запрашивает, чтобы цикл событий Node.js не завершался, пока активен fs.FSWatcher. Многократный вызов watcher.ref() ни на что не влияет.

По умолчанию все объекты fs.FSWatcher уже имеют состояние "ref", поэтому обычно вызывать watcher.ref() не требуется, если ранее не вызывался watcher.unref().

watcher.unref()

При вызове активный объект fs.FSWatcher перестаёт требовать, чтобы цикл событий Node.js оставался активным. Если нет другой активности, поддерживающей цикл событий, процесс может завершиться до вызова callback объекта fs.FSWatcher. Многократный вызов watcher.unref() ни на что не влияет.

Класс: fs.StatWatcher

Успешный вызов метода fs.watchFile() возвращает новый объект fs.StatWatcher.

watcher.ref()

При вызове запрашивает, чтобы цикл событий Node.js не завершался, пока активен fs.StatWatcher. Многократный вызов watcher.ref() ни на что не влияет.

По умолчанию все объекты fs.StatWatcher уже имеют состояние "ref", поэтому обычно вызывать watcher.ref() не требуется, если ранее не вызывался watcher.unref().

watcher.unref()

При вызове активный объект fs.StatWatcher перестаёт требовать, чтобы цикл событий Node.js оставался активным. Если нет другой активности, поддерживающей цикл событий, процесс может завершиться до вызова callback объекта fs.StatWatcher. Многократный вызов watcher.unref() ни на что не влияет.

Класс: fs.ReadStream

Экземпляры fs.ReadStream нельзя создавать напрямую. Они создаются и возвращаются функцией fs.createReadStream().

Событие: 'close'

Генерируется, когда базовый файловый дескриптор fs.ReadStream закрыт.

Событие: 'open'

  • fd <integer> целочисленный файловый дескриптор, используемый fs.ReadStream

Генерируется, когда файловый дескриптор fs.ReadStream открыт.

Событие: 'ready'

Генерируется, когда fs.ReadStream готов к использованию.

Срабатывает сразу после 'open'.

readStream.bytesRead

Количество байтов, прочитанных на данный момент.

readStream.path

Путь к файлу, из которого читает поток, указанный в первом аргументе fs.createReadStream(). Если path передан как строка, readStream.path будет строкой. Если path передан как Buffer, readStream.path будет Buffer. Если указан fd, значение readStream.path будет undefined.

readStream.pending

Это свойство равно true, если базовый файл ещё не был открыт, то есть до генерации события 'ready'.

Класс: fs.Stats

Объект fs.Stats содержит информацию о файле.

Объекты, возвращаемые методами fs.stat(), fs.lstat(), fs.fstat() и их синхронными аналогами, имеют этот тип. Если в options, переданных этим методам, значение bigint равно true, числовые значения будут иметь тип bigint вместо number, а объект также будет содержать дополнительные свойства с наносекундной точностью, оканчивающиеся на Ns. Объекты Stat не следует создавать напрямую через new.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Stats {
  dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atimeMs: 1318289051000.1,
  mtimeMs: 1318289051000.1,
  ctimeMs: 1318289051000.1,
  birthtimeMs: 1318289051000.1,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

Версия с bigint:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BigIntStats {
  dev: 2114n,
  ino: 48064969n,
  mode: 33188n,
  nlink: 1n,
  uid: 85n,
  gid: 100n,
  rdev: 0n,
  size: 527n,
  blksize: 4096n,
  blocks: 8n,
  atimeMs: 1318289051000n,
  mtimeMs: 1318289051000n,
  ctimeMs: 1318289051000n,
  birthtimeMs: 1318289051000n,
  atimeNs: 1318289051000000000n,
  mtimeNs: 1318289051000000000n,
  ctimeNs: 1318289051000000000n,
  birthtimeNs: 1318289051000000000n,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

stats.isBlockDevice()

Возвращает true, если объект fs.Stats описывает блочное устройство.

stats.isCharacterDevice()

Возвращает true, если объект fs.Stats описывает символьное устройство.

stats.isDirectory()

Возвращает true, если объект fs.Stats описывает каталог файловой системы.

Если объект fs.Stats получен вызовом fs.lstat() для символической ссылки, которая указывает на каталог, этот метод вернёт false. Это связано с тем, что fs.lstat() возвращает информацию о самой символической ссылке, а не о пути, к которому она разрешается.

stats.isFIFO()

Возвращает true, если объект fs.Stats описывает FIFO-канал (first-in-first-out).

stats.isFile()

Возвращает true, если объект fs.Stats описывает обычный файл.

stats.isSocket()

Возвращает true, если объект fs.Stats описывает сокет.

Возвращает true, если объект fs.Stats описывает символическую ссылку.

Этот метод корректен только при использовании fs.lstat().

stats.dev

Числовой идентификатор устройства, содержащего файл.

stats.ino

Специфичный для файловой системы номер inode файла.

stats.mode

Битовое поле, описывающее тип и режим файла.

Количество жёстких ссылок, существующих для файла.

stats.uid

Числовой идентификатор пользователя, которому принадлежит файл (POSIX).

stats.gid

Числовой идентификатор группы, которой принадлежит файл (POSIX).

stats.rdev

Числовой идентификатор устройства, если файл представляет устройство.

stats.size

Размер файла в байтах.

Если базовая файловая система не поддерживает получение размера файла, значение будет равно 0.

stats.blksize

Размер блока файловой системы для операций ввода-вывода.

stats.blocks

Количество блоков, выделенных для этого файла.

stats.atimeMs

Временная метка последнего доступа к файлу в миллисекундах с эпохи POSIX.

stats.mtimeMs

Временная метка последнего изменения файла в миллисекундах с эпохи POSIX.

stats.ctimeMs

Временная метка последнего изменения состояния файла в миллисекундах с эпохи POSIX.

stats.birthtimeMs

Временная метка времени создания файла в миллисекундах с эпохи POSIX.

stats.atimeNs

Присутствует только тогда, когда в метод, создающий объект, передано bigint: true. Это временная метка последнего доступа к файлу в наносекундах с эпохи POSIX.

stats.mtimeNs

Присутствует только тогда, когда в метод, создающий объект, передано bigint: true. Это временная метка последнего изменения файла в наносекундах с эпохи POSIX.

stats.ctimeNs

Присутствует только тогда, когда в метод, создающий объект, передано bigint: true. Это временная метка последнего изменения состояния файла в наносекундах с эпохи POSIX.

stats.birthtimeNs

Присутствует только тогда, когда в метод, создающий объект, передано bigint: true. Это временная метка времени создания файла в наносекундах с эпохи POSIX.

stats.atime

Временная метка последнего доступа к этому файлу.

stats.mtime

Временная метка последнего изменения этого файла.

stats.ctime

Временная метка последнего изменения состояния файла.

stats.birthtime

Временная метка времени создания этого файла.

Значения времени Stat

Свойства atimeMs, mtimeMs, ctimeMs, birthtimeMs — это числовые значения, содержащие соответствующее время в миллисекундах. Их точность зависит от платформы. Если в метод, создающий объект, передано bigint: true, эти свойства будут иметь тип bigint, иначе это будут числа.

Свойства atimeNs, mtimeNs, ctimeNs, birthtimeNs — это значения bigint, содержащие соответствующее время в наносекундах. Они присутствуют только тогда, когда в метод, создающий объект, передано bigint: true. Их точность зависит от платформы.

atime, mtime, ctime и birthtime — это альтернативные представления различных моментов времени в виде объектов Date. Значения Date и числовые значения не связаны между собой. Если присвоить новое числовое значение или изменить объект Date, это не отразится на соответствующем альтернативном представлении.

Временные поля объекта stat имеют следующую семантику:

  • atime "Access Time": время последнего доступа к данным файла. Изменяется системными вызовами mknod(2), utimes(2) и read(2).
  • mtime "Modified Time": время последнего изменения данных файла. Изменяется системными вызовами mknod(2), utimes(2) и write(2).
  • ctime "Change Time": время последнего изменения состояния файла (модификации данных inode). Изменяется системными вызовами chmod(2), chown(2), link(2), mknod(2), rename(2), unlink(2), utimes(2), read(2) и write(2).
  • birthtime "Birth Time": время создания файла. Устанавливается один раз при создании файла. В файловых системах, где birthtime недоступно, это поле может вместо этого содержать либо ctime, либо 1970-01-01T00:00Z (то есть Unix-эпоху с меткой времени 0). В таком случае это значение может быть больше, чем atime или mtime. В Darwin и других вариантах FreeBSD оно также устанавливается, если atime явно устанавливается в значение раньше текущего birthtime с помощью системного вызова utimes(2).

До Node.js 0.12 в Windows поле ctime содержало birthtime. Начиная с 0.12, ctime не означает "время создания", и в Unix-системах оно никогда этого не означало.

Класс: fs.StatFs

Содержит информацию о смонтированной файловой системе.

Объекты, возвращаемые fs.statfs() и его синхронным аналогом, имеют этот тип. Если в options, переданных этим методам, значение bigint равно true, числовые значения будут иметь тип bigint вместо number.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
StatFs {
  type: 1397114950,
  bsize: 4096,
  frsize: 4096,
  blocks: 121938943,
  bfree: 61058895,
  bavail: 61058895,
  files: 999,
  ffree: 1000000
}

Версия с bigint:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
StatFs {
  type: 1397114950n,
  bsize: 4096n,
  frsize: 4096n,
  blocks: 121938943n,
  bfree: 61058895n,
  bavail: 61058895n,
  files: 999n,
  ffree: 1000000n
}

statfs.bavail

Свободные блоки, доступные непривилегированным пользователям.

statfs.bfree

Свободные блоки в файловой системе.

statfs.blocks

Общее количество блоков данных в файловой системе.

statfs.bsize

Оптимальный размер блока передачи.

statfs.frsize

Базовый размер блока файловой системы.

statfs.ffree

Свободные файловые узлы в файловой системе.

statfs.files

Общее количество файловых узлов в файловой системе.

statfs.type

Тип файловой системы.

Класс: fs.Utf8Stream

Стабильность: 1 - Экспериментальная

Оптимизированный UTF-8-писатель потока, который позволяет по запросу сбрасывать весь внутренний буфер. Корректно обрабатывает ошибки EAGAIN, что позволяет настраивать поведение, например отбрасывать содержимое, если диск занят.

Событие: 'close'

Событие 'close' генерируется, когда поток полностью закрыт.

Событие: 'drain'

Событие 'drain' генерируется, когда внутренний буфер достаточно освободился, чтобы можно было продолжить запись.

Событие: 'drop'

Событие 'drop' генерируется, когда достигнута максимальная длина и эти данные не будут записаны. Отброшенные данные передаются первым аргументом обработчику события.

Событие: 'error'

Событие 'error' генерируется при возникновении ошибки.

Событие: 'finish'

Событие 'finish' генерируется, когда поток завершён и все данные сброшены в базовый файл.

Событие: 'ready'

Событие 'ready' генерируется, когда поток готов принимать запись.

Событие: 'write'

Событие 'write' генерируется, когда операция записи завершена. Количество записанных байтов передаётся первым аргументом обработчику события.

new fs.Utf8Stream([options])

  • options <Object>
    • append: boolean добавлять запись в файл dest, а не усекать его. По умолчанию: true.
    • contentMode: string какой тип данных можно передавать в функцию записи; поддерживаются значения 'utf8' и 'buffer'. По умолчанию: 'utf8'.
    • dest: string путь к файлу, в который будет вестись запись (режим управляется опцией append).
    • fd: number файловый дескриптор, например возвращаемый fs.open() или fs.openSync().
    • fs: Object объект с тем же API, что и модуль fs; полезен для моков, тестирования или настройки поведения потока.
    • fsync: boolean выполнять fs.fsyncSync() после каждого завершённого вызова записи.
    • maxLength: number максимальная длина внутреннего буфера. Если операция записи приведёт к превышению maxLength, записываемые данные будут отброшены и будет сгенерировано событие drop с этими данными.
    • maxWrite: number максимальное число байтов, которое можно записать; По умолчанию: 16384
    • minLength: number минимальная длина внутреннего буфера, которую нужно набрать перед сбросом.
    • mkdir: boolean если true, гарантирует существование каталога для файла dest. По умолчанию: false.
    • mode: number | string режим создаваемого файла (см. fs.open()).
    • periodicFlush: number вызывает сброс каждые periodicFlush миллисекунд.
    • retryEAGAIN <Function> функция, вызываемая, когда write(), writeSync() или flushSync() сталкиваются с ошибкой EAGAIN или EBUSY. Если возвращаемое значение равно true, операция будет повторена, иначе ошибка всплывёт наружу. err — ошибка, вызвавшая этот вызов функции, writeBufferLen — длина буфера, который был записан, а remainingBufferLen — длина оставшегося буфера, который поток не пытался записать.
    • sync: boolean выполнять запись синхронно.

utf8Stream.append

  • boolean указывает, добавляет ли поток данные в файл или усекает его.

utf8Stream.contentMode

  • string тип данных, которые можно записывать в поток. Поддерживаются значения 'utf8' и 'buffer'. По умолчанию: 'utf8'.

utf8Stream.destroy()

Немедленно закрывает поток без сброса внутреннего буфера.

utf8Stream.end()

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

utf8Stream.fd

  • number файловый дескриптор, в который выполняется запись.

utf8Stream.file

  • string файл, в который выполняется запись.

utf8Stream.flush(callback)

  • callback <Function>
    • err <Error> | null ошибка, если сброс завершился неудачей, иначе null

Записывает текущий буфер в файл, если запись в данный момент не выполняется. Ничего не делает, если minLength равно нулю или если поток уже пишет.

utf8Stream.flushSync()

Синхронно сбрасывает буферизованные данные. Это затратная операция.

utf8Stream.fsync

  • boolean указывает, выполняет ли поток fs.fsyncSync() после каждой операции записи.

utf8Stream.maxLength

  • number максимальная длина внутреннего буфера. Если операция записи приведёт к превышению maxLength, записываемые данные будут отброшены и будет сгенерировано событие drop с отброшенными данными.

utf8Stream.minLength

  • number минимальная длина внутреннего буфера, которую нужно заполнить перед сбросом.

utf8Stream.mkdir

  • boolean указывает, должен ли поток обеспечивать существование каталога для файла dest. Если true, каталог будет создан, если он отсутствует. По умолчанию: false.

utf8Stream.mode

  • number | string режим файла, в который выполняется запись.

utf8Stream.periodicFlush

  • number количество миллисекунд между сбросами. Если установлено 0, периодические сбросы выполняться не будут.

utf8Stream.reopen(file)

  • file: string | Buffer | URL путь к файлу, в который будет вестись запись (режим управляется опцией append)

Повторно открывает файл на месте; полезно для ротации логов.

utf8Stream.sync

  • boolean указывает, пишет ли поток синхронно или асинхронно.

utf8Stream.write(data)

Если при создании потока options.contentMode установлен в 'utf8', аргумент data должен быть строкой. Если contentMode установлен в 'buffer', аргумент data должен быть Buffer.

utf8Stream.writing

  • boolean указывает, записывает ли поток данные в файл в данный момент.

utf8Stream[Symbol.dispose]()

Вызывает utf8Stream.destroy().

Класс: fs.WriteStream

Экземпляры fs.WriteStream нельзя создавать напрямую. Они создаются и возвращаются функцией fs.createWriteStream().

Событие: 'close'

Генерируется, когда базовый файловый дескриптор fs.WriteStream закрыт.

Событие: 'open'

  • fd <integer> целочисленный файловый дескриптор, используемый fs.WriteStream

Генерируется, когда файл fs.WriteStream открыт.

Событие: 'ready'

Генерируется, когда fs.WriteStream готов к использованию.

Срабатывает сразу после 'open'.

writeStream.bytesWritten

Количество байтов, записанных на данный момент. Не включает данные, которые всё ещё находятся в очереди на запись.

writeStream.close([callback])

Закрывает writeStream. Необязательно принимает callback, который будет выполнен после закрытия writeStream.

writeStream.path

Путь к файлу, в который пишет поток, указанный в первом аргументе fs.createWriteStream(). Если path передан как строка, writeStream.path будет строкой. Если path передан как Buffer, writeStream.path будет Buffer.

writeStream.pending

Это свойство равно true, если базовый файл ещё не был открыт, то есть до генерации события 'ready'.

fs.constants

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

Константы FS

Следующие константы экспортируются через fs.constants и fsPromises.constants.

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

Чтобы использовать несколько констант одновременно, применяйте оператор побитового ИЛИ |.

Пример:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { open, constants } from 'node:fs';

const {
  O_RDWR,
  O_CREAT,
  O_EXCL,
} = constants;

open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
  // ...
});
Константы доступа к файлам

Следующие константы предназначены для использования в качестве параметра mode, передаваемого в fsPromises.access(), fs.access() и fs.accessSync().

Константа Описание
F_OK Флаг, указывающий, что файл видим для вызывающего процесса. Полезен для проверки существования файла, но ничего не говорит о правах rwx. Используется по умолчанию, если режим не указан.
R_OK Флаг, указывающий, что файл может быть прочитан вызывающим процессом.
W_OK Флаг, указывающий, что в файл можно записывать из вызывающего процесса.
X_OK Флаг, указывающий, что файл может быть выполнен вызывающим процессом. В Windows не оказывает эффекта (ведёт себя как fs.constants.F_OK).

Эти определения также доступны в Windows.

Константы копирования файлов

Следующие константы предназначены для использования с fs.copyFile().

Константа Описание
COPYFILE_EXCL Если указана, операция копирования завершится ошибкой, если целевой путь уже существует.
COPYFILE_FICLONE Если указана, операция копирования попытается создать reflink с копированием по записи. Если базовая платформа не поддерживает copy-on-write, используется запасной механизм копирования.
COPYFILE_FICLONE_FORCE Если указана, операция копирования попытается создать reflink с копированием по записи. Если базовая платформа не поддерживает copy-on-write, операция завершится ошибкой.

Эти определения также доступны в Windows.

Константы открытия файлов

Следующие константы предназначены для использования с fs.open().

Константа Описание
O_RDONLY Флаг, указывающий, что файл следует открыть только для чтения.
O_WRONLY Флаг, указывающий, что файл следует открыть только для записи.
O_RDWR Флаг, указывающий, что файл следует открыть для чтения и записи.
O_CREAT Флаг, указывающий, что файл следует создать, если он ещё не существует.
O_EXCL Флаг, указывающий, что открытие файла должно завершиться ошибкой, если установлен флаг O_CREAT и файл уже существует.
O_NOCTTY Флаг, указывающий, что если path обозначает терминальное устройство, его открытие не должно делать этот терминал управляющим терминалом процесса (если у процесса его ещё нет).
O_TRUNC Флаг, указывающий, что если файл существует и является обычным файлом, а также успешно открыт для записи, его длина будет усечена до нуля.
O_APPEND Флаг, указывающий, что данные будут добавляться в конец файла.
O_DIRECTORY Флаг, указывающий, что открытие должно завершиться ошибкой, если path не является каталогом.
O_NOATIME Флаг, указывающий, что операции чтения из файловой системы больше не будут приводить к обновлению связанного с файлом значения atime. Этот флаг доступен только в Linux.
O_NOFOLLOW Флаг, указывающий, что открытие должно завершиться ошибкой, если path является символической ссылкой.
O_SYNC Флаг, указывающий, что файл открывается для синхронизированного ввода-вывода, при котором операции записи ждут сохранения целостности файла.
O_DSYNC Флаг, указывающий, что файл открывается для синхронизированного ввода-вывода, при котором операции записи ждут сохранения целостности данных.
O_SYMLINK Флаг, указывающий, что следует открыть саму символическую ссылку, а не ресурс, на который она указывает.
O_DIRECT Если установлен, будет предпринята попытка минимизировать влияние кэширования на файловый ввод-вывод.
O_NONBLOCK Флаг, указывающий, что файл следует открыть в неблокирующем режиме, если это возможно.
UV_FS_O_FILEMAP Если установлен, для доступа к файлу используется отображение файла в память. Этот флаг доступен только в Windows. В других операционных системах он игнорируется.

В Windows доступны только O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY и UV_FS_O_FILEMAP.

Константы типа файла

Следующие константы предназначены для использования со свойством mode объекта fs.Stats для определения типа файла.

Константа Описание
S_IFMT Битовая маска, используемая для извлечения кода типа файла.
S_IFREG Константа типа для обычного файла.
S_IFDIR Константа типа для каталога.
S_IFCHR Константа типа для символьного устройства.
S_IFBLK Константа типа для блочного устройства.
S_IFIFO Константа типа для FIFO/канала.
S_IFLNK Константа типа для символической ссылки.
S_IFSOCK Константа типа для сокета.

В Windows доступны только S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT и S_IFREG.

Константы режима файла

Следующие константы предназначены для использования со свойством mode объекта fs.Stats для определения прав доступа к файлу.

Константа Описание
S_IRWXU Режим файла, указывающий, что владелец может читать, записывать и выполнять файл.
S_IRUSR Режим файла, указывающий, что владелец может читать файл.
S_IWUSR Режим файла, указывающий, что владелец может записывать в файл.
S_IXUSR Режим файла, указывающий, что владелец может выполнять файл.
S_IRWXG Режим файла, указывающий, что группа может читать, записывать и выполнять файл.
S_IRGRP Режим файла, указывающий, что группа может читать файл.
S_IWGRP Режим файла, указывающий, что группа может записывать в файл.
S_IXGRP Режим файла, указывающий, что группа может выполнять файл.
S_IRWXO Режим файла, указывающий, что остальные могут читать, записывать и выполнять файл.
S_IROTH Режим файла, указывающий, что остальные могут читать файл.
S_IWOTH Режим файла, указывающий, что остальные могут записывать в файл.
S_IXOTH Режим файла, указывающий, что остальные могут выполнять файл.

В Windows доступны только S_IRUSR и S_IWUSR.

Примечания

Порядок выполнения операций с обратными вызовами и промисами

Поскольку эти операции выполняются асинхронно базовым пулом потоков, при использовании методов на основе обратных вызовов или промисов порядок их выполнения не гарантируется.

Например, следующий код подвержен ошибкам, потому что операция fs.stat() может завершиться раньше, чем fs.rename():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const fs = require('node:fs');

fs.rename('/tmp/hello', '/tmp/world', (err) => {
    if (err) throw err;
    console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
});

Важно правильно упорядочивать операции: дождаться результата одной, прежде чем вызывать другую:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { rename, stat } from 'node:fs/promises';

const oldPath = '/tmp/hello';
const newPath = '/tmp/world';

try {
  await rename(oldPath, newPath);
  const stats = await stat(newPath);
  console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
  console.error('there was an error:', error.message);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const { rename, stat } = require('node:fs/promises');

(async function(oldPath, newPath) {
  try {
    await rename(oldPath, newPath);
    const stats = await stat(newPath);
    console.log(`stats: ${JSON.stringify(stats)}`);
  } catch (error) {
    console.error('there was an error:', error.message);
  }
})('/tmp/hello', '/tmp/world');

Или, если используются callback API, перенести вызов fs.stat() внутрь обратного вызова операции fs.rename():

1
2
3
4
5
6
7
8
9
import { rename, stat } from 'node:fs';

rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
  });
});
1
2
3
4
5
6
7
8
9
const { rename, stat } = require('node:fs/promises');

rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
  });
});

Пути к файлам

Большинство операций fs принимают пути к файлам, которые могут быть указаны в виде строки, Buffer или объекта URL с протоколом file:.

Строковые пути

Строковые пути интерпретируются как последовательности символов UTF-8, задающие абсолютное или относительное имя файла. Относительные пути разрешаются относительно текущего рабочего каталога, определяемого вызовом process.cwd().

Пример использования абсолютного пути в POSIX:

1
2
3
4
5
6
7
8
9
import { open } from 'node:fs/promises';

let fd;
try {
  fd = await open('/open/some/file.txt', 'r');
  // Сделать что-нибудь с файлом
} finally {
  await fd?.close();
}

Пример использования относительного пути в POSIX (относительно process.cwd()):

1
2
3
4
5
6
7
8
9
import { open } from 'node:fs/promises';

let fd;
try {
  fd = await open('file.txt', 'r');
  // Сделать что-нибудь с файлом
} finally {
  await fd?.close();
}

URL-пути к файлам

Для большинства функций модуля node:fs аргумент path или filename можно передавать как объект URL с использованием протокола file:.

1
2
3
import { readFileSync } from 'node:fs';

readFileSync(new URL('file:///tmp/hello'));

URL file: всегда являются абсолютными путями.

Платформенные особенности

В Windows объекты URL с протоколом file: и именем хоста преобразуются в UNC-пути, а объекты URL с протоколом file: и буквами дисков преобразуются в локальные абсолютные пути. Объекты URL с протоколом file: без имени хоста и без буквы диска приводят к ошибке:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { readFileSync } from 'node:fs';
// В Windows:

// - URL файлов WHATWG с именем хоста преобразуются в UNC-путь
// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
readFileSync(new URL('file://hostname/p/a/t/h/file'));

// - URL файлов WHATWG с буквами дисков преобразуются в абсолютный путь
// file:///C:/tmp/hello => C:\tmp\hello
readFileSync(new URL('file:///C:/tmp/hello'));

// - URL файлов WHATWG без имени хоста должны содержать букву диска
readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
readFileSync(new URL('file:///c/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute

Объекты URL с протоколом file: и буквами дисков должны использовать : как разделитель сразу после буквы диска. Использование другого разделителя приведёт к ошибке.

На всех остальных платформах объекты URL с протоколом file: и именем хоста не поддерживаются и приводят к ошибке:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { readFileSync } from 'node:fs';
// На других платформах:

// - URL файлов WHATWG с именем хоста не поддерживаются
// file://hostname/p/a/t/h/file => throw!
readFileSync(new URL('file://hostname/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute

// - URL файлов WHATWG преобразуются в абсолютный путь
// file:///tmp/hello => /tmp/hello
readFileSync(new URL('file:///tmp/hello'));

Объекты URL с протоколом file: и закодированными символами слеша приводят к ошибке на всех платформах:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { readFileSync } from 'node:fs';

// В Windows
readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */

// В POSIX
readFileSync(new URL('file:///p/a/t/h/%2F'));
readFileSync(new URL('file:///p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
/ characters */

В Windows объекты URL с протоколом file: и закодированной обратной косой чертой приводят к ошибке:

1
2
3
4
5
6
7
import { readFileSync } from 'node:fs';

// В Windows
readFileSync(new URL('file:///C:/path/%5C'));
readFileSync(new URL('file:///C:/path/%5c'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */

Пути через Buffer

Пути, заданные через Buffer, полезны прежде всего в некоторых POSIX-совместимых операционных системах, которые рассматривают пути к файлам как непрозрачные последовательности байтов. В таких системах один путь к файлу может содержать подпоследовательности с разными кодировками символов. Как и строковые пути, пути Buffer могут быть относительными или абсолютными:

Пример использования абсолютного пути в POSIX:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { open } from 'node:fs/promises';
import { Buffer } from 'node:buffer';

let fd;
try {
  fd = await open(Buffer.from('/open/some/file.txt'), 'r');
  // Сделать что-нибудь с файлом
} finally {
  await fd?.close();
}

Рабочие каталоги для каждого диска в Windows

В Windows Node.js придерживается концепции отдельного рабочего каталога для каждого диска. Это поведение можно наблюдать при использовании пути к диску без обратной косой черты. Например, fs.readdirSync('C:\\') потенциально может вернуть другой результат, чем fs.readdirSync('C:'). Подробнее см. на этой странице Microsoft Learn.

Файловые дескрипторы

В POSIX-системах ядро для каждого процесса поддерживает таблицу текущих открытых файлов и ресурсов. Каждому открытому файлу присваивается простой числовой идентификатор, называемый файловым дескриптором. На системном уровне все операции файловой системы используют эти файловые дескрипторы для идентификации и отслеживания конкретных файлов. В Windows используется другой, но концептуально похожий механизм отслеживания ресурсов. Чтобы упростить работу пользователям, Node.js скрывает различия между операционными системами и присваивает всем открытым файлам числовой файловый дескриптор.

Методы fs.open() на основе обратного вызова и синхронный fs.openSync() открывают файл и выделяют новый файловый дескриптор. После этого дескриптор можно использовать для чтения, записи или запроса информации о файле.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { open, close, fstat } from 'node:fs';

function closeFd(fd) {
  close(fd, (err) => {
    if (err) throw err;
  });
}

open('/open/some/file.txt', 'r', (err, fd) => {
  if (err) throw err;
  try {
    fstat(fd, (err, stat) => {
      if (err) {
        closeFd(fd);
        throw err;
      }

      // использовать stat

      closeFd(fd);
    });
  } catch (err) {
    closeFd(fd);
    throw err;
  }
});

API на основе промисов используют объект FileHandle вместо числового файлового дескриптора. Система лучше управляет такими объектами, чтобы предотвратить утечки ресурсов. Тем не менее, по завершении операций их всё равно необходимо закрывать:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { open } from 'node:fs/promises';

let file;
try {
  file = await open('/open/some/file.txt', 'r');
  const stat = await file.stat();
  // использовать stat
} finally {
  await file.close();
}

Использование пула потоков

Все файловые API на основе обратных вызовов и промисов (за исключением fs.FSWatcher()) используют пул потоков libuv. Для некоторых приложений это может иметь неожиданные и негативные последствия для производительности. Подробнее см. документацию UV_THREADPOOL_SIZE.

Флаги файловой системы

Следующие флаги доступны везде, где параметр flag принимает строку.

  • 'a': Открыть файл для добавления. Если файла нет, он будет создан.
  • 'ax': То же, что 'a', но операция завершится ошибкой, если путь уже существует.
  • 'a+': Открыть файл для чтения и добавления. Если файла нет, он будет создан.
  • 'ax+': То же, что 'a+', но операция завершится ошибкой, если путь уже существует.
  • 'as': Открыть файл для добавления в синхронном режиме. Если файла нет, он будет создан.
  • 'as+': Открыть файл для чтения и добавления в синхронном режиме. Если файла нет, он будет создан.
  • 'r': Открыть файл для чтения. Если файл не существует, возникнет исключение.
  • 'rs': Открыть файл для чтения в синхронном режиме. Если файл не существует, возникнет исключение.
  • 'r+': Открыть файл для чтения и записи. Если файл не существует, возникнет исключение.
  • 'rs+': Открыть файл для чтения и записи в синхронном режиме. Указывает операционной системе обойти локальный кэш файловой системы.

    Это прежде всего полезно при открытии файлов на NFS-монтированиях, поскольку позволяет обойти потенциально устаревший локальный кэш. Этот флаг ощутимо влияет на производительность ввода-вывода, поэтому использовать его без необходимости не рекомендуется.

    Это не превращает fs.open() или fsPromises.open() в синхронный блокирующий вызов. Если требуется синхронная операция, следует использовать, например, fs.openSync().

  • 'w': Открыть файл для записи. Файл создаётся (если его нет) или усекается (если он существует).

  • 'wx': То же, что 'w', но операция завершится ошибкой, если путь уже существует.
  • 'w+': Открыть файл для чтения и записи. Файл создаётся (если его нет) или усекается (если он существует).
  • 'wx+': То же, что 'w+', но операция завершится ошибкой, если путь уже существует.

flag также может быть числом, как описано в open(2); часто используемые константы доступны через fs.constants. В Windows флаги при необходимости преобразуются в эквиваленты, например O_WRONLY в FILE_GENERIC_WRITE, а O_EXCL|O_CREAT в CREATE_NEW, который принимает CreateFileW.

Эксклюзивный флаг 'x' (флаг O_EXCL в open(2)) приводит к ошибке, если путь уже существует. В POSIX, если путь является символической ссылкой, использование O_EXCL возвращает ошибку, даже если ссылка указывает на несуществующий путь. Эксклюзивный флаг может не работать с сетевыми файловыми системами.

В Linux позиционная запись не работает, когда файл открыт в режиме добавления. Ядро игнорирует аргумент позиции и всегда дописывает данные в конец файла.

Чтобы изменить существующий файл вместо его замены, может потребоваться установить flag в 'r+', а не использовать значение по умолчанию 'w'.

Поведение некоторых флагов зависит от платформы. Например, открытие каталога на macOS и Linux с флагом 'a+', как в примере ниже, завершится ошибкой. Напротив, в Windows и FreeBSD будет возвращён файловый дескриптор или FileHandle.

1
2
3
4
5
6
7
8
9
// macOS и Linux
fs.open('<directory>', 'a+', (err, fd) => {
    // => [Error: EISDIR: illegal operation on a directory, open <directory>]
});

// Windows и FreeBSD
fs.open('<directory>', 'a+', (err, fd) => {
    // => null, <fd>
});

В Windows открытие существующего скрытого файла с флагом 'w' (через fs.open(), fs.writeFile() или fsPromises.open()) завершится ошибкой EPERM. Для записи в существующие скрытые файлы можно использовать флаг 'r+'.

Для сброса содержимого файла можно вызвать fs.ftruncate() или filehandle.truncate().

Комментарии