Menu

Запись в файл в Node.js: fs.writeFile и appendFile

Файл в Node.js записывают через fs.writeFile, fs.writeFileSync или await writeFile из fs/promises. Если файла нет, он создаётся, а если есть, заменяется; чтобы дописать в конец, используйте appendFile.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

fs.writeFile(path, data, callback) записывает строку или Buffer в файл. Если файла нет, Node его создаёт; если есть, старое содержимое заменяется. fs.writeFileSync(path, data) делает то же самое и ждёт окончания записи, а fs.appendFile дописывает в конец файла, а не заменяет его.

Программа выводит saved, а затем текст, прочитанный обратно; callback получает только ошибку (или null), но никогда не данные. Передайте 42 вместо строки, и вызов выбросит TypeError: данные должны быть строкой или Buffer.

writeFile, writeFileSync и fs/promises

Три формы принимают одинаковые аргументы и отличаются тем, как вы ждёте результат.

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

fs.writeFileSync('a.txt', 'one');            // blocks, throws on error

fs.writeFile('b.txt', 'two', (err) => {});   // callback with err

await fsp.writeFile('c.txt', 'three');       // promise, use in async code

Используйте writeFileSync в скриптах и коде запуска, а версию на промисах на серверах, где синхронная запись блокирует все остальные запросы, пока диск не закончит. Остальной API на промисах показан на странице про fs/promises.

Дописать в файл через appendFile

writeFile заменяет файл целиком. Чтобы добавить строку в лог, используйте appendFile, который в первый раз тоже создаёт файл.

Первое чтение выводит "second\n", потому что второй writeFileSync заменил first, а второе выводит "second\nthird\nfourth\n" (JSON.stringify делает переводы строк видимыми). Добавляйте \n сами: ни одна из функций его не добавляет.

writeFileappendFile
Файла нетСоздаёт егоСоздаёт его
Файл естьЗаменяет содержимоеДописывает в конец
Флаг по умолчанию'w''a'
Для чего обычноСохранить документ или JSON целикомЛоги, по одной строке

Не перезаписывать: опция flag

Третьим аргументом можно передать объект опций. Его flag решает, что будет с существующим файлом. 'wx' значит «записать, но упасть, если файл уже есть», и это безопасный способ создать файл только один раз.

Второй вызов падает с EEXIST, поэтому в файле по-прежнему abc123. Поменяйте имя файла во втором вызове на id2.txt, и оба вызова выведут created.

Флаги, которые встречаются чаще всего: 'w' (по умолчанию, заменить), 'a' (дописать), 'wx' (только создать) и 'ax' (дописать, но только в новый файл).

Если сначала проверить через fs.existsSync, а потом записать, остаётся щель: другой процесс может создать файл между проверкой и записью. 'wx' делает и то и другое за один шаг.

Запись JSON в файл

writeFile не принимает объекты. Превратите их в текст через JSON.stringify; третий аргумент, 2, добавляет отступы, чтобы файл было удобно читать.

В файле объект записан на нескольких строках с отступами, а после разбора получается такой же объект, поэтому последняя строка выводит 2. Передайте объект без JSON.stringify, и вызов выбросит TypeError.

Сначала создайте папку через mkdir

writeFile создаёт файлы, но не папки. Запись в reports/2026/june.txt, когда папки reports нет, падает с ENOENT. Сначала создайте путь через mkdir с { recursive: true }: он создаёт все недостающие папки и ничего не делает, если они уже есть.

Первая запись падает с ENOENT; после mkdir та же запись проходит, и readdir показывает [ 'june.txt' ]. В настоящем коде собирайте такие пути через path.join, чтобы они работали и в Windows.

Частые ошибки

Ожидание, что файл записан сразу после вызова. fs.writeFile возвращается раньше, чем данные окажутся на диске. Читайте файл или переходите к следующему шагу внутри callback'а или дождитесь версии на промисах через await.

Потеря данных при записи в цикле. Вызов writeFile для каждого элемента каждый раз заменяет файл, и в нём остаётся только последний элемент. Используйте appendFile или соберите всю строку и запишите её один раз.

Запись [object Object]. Если пропустить объект через String() или шаблонную строку, запишется [object Object]. Используйте JSON.stringify.

Часто задаваемые вопросы

fs.writeFile перезаписывает файл?

Да. С флагом по умолчанию 'w' он обрезает файл и записывает новые данные, так что старое содержимое пропадает. Чтобы дописать в конец, передайте { flag: 'a' } или используйте appendFile.

fs.writeFile создаёт файл, если его нет?

Да, файл он создаёт. А вот недостающие папки нет: запись в logs/app.log, когда папки logs нет, падает с ENOENT.

Что можно передать как данные?

Строку, Buffer или типизированный массив. Всё остальное, например объект или число, выбрасывает TypeError, поэтому сначала преобразуйте объекты через JSON.stringify, а числа через String().

Можно ли вызывать writeFile много раз одновременно для одного файла?

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

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

Начать