Модуль fs Node.js
Для работы с файлами в Node.js предназначен модуль fs, который позволяет взаимодействовать с файловой системой по образцу стандартных функций POSIX (Portable Operating System Interface — переносимый интерфейс операционных систем, набор стандартов, описывающих интерфейсы между операционной системой и прикладной программой (системный API), библиотеку языка C и набор приложений и их интерфейсов).
Читай также Работа с модулями в Node.JS
Для использования API модуля fs его необходимо импортировать:
- на основе Promise (Promises API подробнее):
1 |
import * as fs from 'fs/promises'; |
- на основе API обратного вызова (Callback API подробнее) и синхронных функций (API подробнее):
1 |
import * as fs from 'fs'; |
Все операции файловой системы имеют API формы синхронных функций, формы функций обратного вызова и Promises, и доступны с использованием как синтаксиса CommonJS, так и модулей ES6 (ESM).
Версии API-интерфейсов модуля fs на основе обратного вызова (callback) предпочтительнее использования API-интерфейсов обещаний, когда требуется максимальная производительность (как с точки зрения времени выполнения, так и с точки зрения выделения памяти).
Операции на основе Promise возвращают promise, которое выполняется после завершения асинхронной операции (пример):
1 2 3 4 5 6 7 8 |
import { unlink } from 'fs/promises'; try { await unlink('/tmp/hello'); console.log('successfully deleted /tmp/hello'); } catch (error) { console.error('there was an error:', error.message); } |
Форма на основе callback принимает функцию обратного вызова в качестве последнего аргумента и вызывает операцию асинхронно (первый аргумент всегда зарезервирован для исключения). Аргументы, передаваемые в callback, зависят от метода.
Если операция завершена успешно, то первый аргумент имеет значение null или undefined.
1 2 3 4 5 6 |
import { unlink } from 'fs'; unlink('/tmp/hello', (err) => { if (err) throw err; console.log('successfully deleted /tmp/hello'); }); |
Синхронные вызовы блокируют цикл событий Node.js и дальнейшее выполнение JavaScript до завершения операции. Исключения генерируются немедленно и могут быть обработаны с помощью try…catch или могут всплывать.
1 2 3 4 5 6 7 8 |
import { unlinkSync } from 'fs'; try { unlinkSync('/tmp/hello'); console.log('successfully deleted /tmp/hello'); } catch (err) { // handle the error } |
Чтение из файла в Node.js
Допустим, в папке с файлом приложения app.js расположен текстовый файл hello.txt. Перед использованием методов необходимо импортировать нужную функциональность, например:
1 |
import { writeFile, readFileSync, readFile } from "fs"; |
Для чтения текстового файла hello.txt в синхронном варианте применяется функция fs.readFileSync("path" [, options]):
1 2 |
let fileContent = readFileSync("./node/hello.txt", "utf8"); console.log(fileContent); |
где
- "path" - имя или дескриптор файла (например, путь к файлу относительно файла приложения app.js);
- [, options] (например, "utf8" - кодировка для получения текстового содержимого файла).
Функция fs.readFileSync() вернет считанный текст.
Для асинхронного чтения файла применяется функция fs.readFile(path[, options], callback) (подробнее):
1 2 |
import { readFile } from "fs"; readFile("hello.txt", "utf8", function(error,data){ }); |
где
- "path" - имя или дескриптор файла (например, путь к файлу относительно файла приложения app.js);
- [, options] (например, "utf8" - кодировка для получения текстового содержимого файла);
- function(error,data){ } - функция обратного вызова, которая выполняется после завершения чтения (первый параметр функции хранит информацию об ошибке при её наличии, а второй - собственно считанные данные).
Например:
1 2 3 4 5 6 7 |
import { readFile } from 'node:fs/promises'; readFile("./node/hello.txt", "utf8", function (error, data) { console.log("Асинхронное чтение файла"); if (error) throw error; // если возникла ошибка console.log(data); // выводим прочитанные данные (содержимое hello.txt) }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Функция, которая вычисляет хэш SHA256 для файла fileToHash.txt и записывает его в консоль как hex import { createHash } from 'crypto' import { readFile } from 'node:fs/promises'; import { fileURLToPath } from 'url'; import * as path from 'path' const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename) const FILE_NAME = path.join(__dirname, 'files', 'fileToHash.txt') const calculateHash = async () => { const inputData = await readFile(FILE_NAME) const fileHash = createHash('sha256').update(inputData).digest('hex') console.log("fileHash (hex)", fileHash) }; await calculateHash(); |
Запись файла в Node.js
Для записи файла используются функции:
- в синхронном варианте - writeFileSync(file, data[, options]);
- в асинхронном варианте - writeFile(file, data[, options]).
Вышеуказанные методы полностью перезаписывают файл. Если надо дописать файл (присоединить данные к концу файла), то применяются методы appendFile() и appendFileSync().
1 2 3 4 5 6 7 |
appendFile("./node/hello.txt", "Привет? это добавка!", function (error) { if (error) throw error; // если ошибка console.log("Запись файла завершена. Содержимое файла:"); let data = readFileSync("./node/hello.txt", "utf8"); console.log(data); // выводим прочитанные данные }); |
Ещё пример:
1 2 3 4 5 6 7 |
import * as path from 'path' import url from 'url' export const FILE_PATH = url.fileURLToPath(import.meta.url) export const DIR_PATH = path.dirname(FILE_PATH) export const ERROR_MSG = 'FS operation failed' export const SUCCESS_MSG = 'FS operation success' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import * as fs from 'node:fs/promises'; import { DIR_PATH, ERROR_MSG, SUCCESS_MSG } from './constants.js' const FILE_NAME = 'fresh.txt' const FILE_CONTENT = 'I am fresh and young' const create = async () => { try { await fs.writeFile(`${DIR_PATH}/files/${FILE_NAME}`, FILE_CONTENT, { flag: 'wx' }) .then(() => { console.info(SUCCESS_MSG) }) } catch (error) { throw new Error(ERROR_MSG); } } await create(); |
Удаление файла в Node.js
Для удаления файла используются функции:
- в синхронном варианте - unlinkSync(path);
- в асинхронном варианте - unlinkSync(path).
1 2 3 4 5 6 7 8 |
import { unlink } from "fs/promises"; try { unlink("./node/hello.txt"); console.log("успешное удаление ./node/hello.txt"); } catch (error) { console.error("there was an error:", error.message); } |
Еще пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { existsSync, unlink } from "node:fs" const delFilePath = './src/fs/files/fileToRemove.txt' const remove = async (delFilePath) => { try { if (existsSync(delFilePath)) { unlink(delFilePath, (err) => { if (err) throw "Delete operation failed"; }) } else { throw "FS operation failed (file is missing)" } } catch (error) { console.error("ERROR: ", error) } }; await remove(delFilePath); |