Что такое Buffer в Node.js?

MiddleNode.js · Backend·Обновлено 16 июля 2026
Коротко
Buffer — это встроенный класс Node.js для работы с бинарными данными фиксированного размера напрямую в памяти, вне кучи V8. Используется при чтении файлов, сетевом взаимодействии и работе с потоками.

Что такое Buffer

Buffer — это глобальный класс Node.js, предназначенный для работы с сырыми бинарными данными. В отличие от строк JavaScript, которые хранятся в куче V8 и всегда закодированы в UTF-16, Buffer выделяет память вне кучи V8 (через malloc/mmap) и хранит байты напрямую.

Buffer появился ещё до того, как в браузерах появился стандарт TypedArray. Сегодня Buffer наследуется от Uint8Array, поэтому он полностью совместим с WebAPI и стандартными типизированными массивами.

Зачем нужен Buffer

JavaScript исторически был языком для работы с текстом. Но при работе с:

  • файловой системой (fs.readFile)
  • TCP/UDP-сокетами
  • HTTP-потоками
  • криптографией
  • бинарными протоколами (protobuf, msgpack)

...необходимо оперировать отдельными байтами, а не символами Unicode. Buffer решает эту задачу.

Создание Buffer

// Выделить буфер из 10 байт (заполнен нулями)
const buf1 = Buffer.alloc(10);

// Выделить буфер из 10 байт без инициализации (быстрее, но может содержать мусор)
const buf2 = Buffer.allocUnsafe(10);

// Создать из строки
const buf3 = Buffer.from('Привет', 'utf-8');

// Создать из массива байт
const buf4 = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]);

// Создать из другого Buffer или Uint8Array
const buf5 = Buffer.from(buf3);

Кодировки

Buffer поддерживает несколько кодировок при преобразовании в строку и обратно:

const buf = Buffer.from('Hello');

console.log(buf.toString('utf-8'));   // Hello
console.log(buf.toString('hex'));     // 48656c6c6f
console.log(buf.toString('base64'));  // SGVsbG8=

Поддерживаемые кодировки: utf-8, utf-16le, latin1, base64, base64url, hex, ascii, binary.

Основные операции

const buf = Buffer.alloc(4);

// Запись числа в буфер (Big Endian)
buf.writeUInt32BE(0xDEADBEEF, 0);

// Чтение числа
console.log(buf.readUInt32BE(0).toString(16)); // deadbeef

// Срез (возвращает view, не копию!)
const slice = buf.slice(0, 2);

// Копирование
const dest = Buffer.alloc(2);
buf.copy(dest, 0, 0, 2);

// Сравнение
console.log(buf.equals(dest)); // false

// Конкатенация
const joined = Buffer.concat([buf, dest]);
console.log(joined.length); // 6

Buffer.alloc vs Buffer.allocUnsafe

Buffer.alloc(size) заполняет выделенную память нулями — безопасно, но медленнее. Buffer.allocUnsafe(size) не обнуляет память, поэтому может содержать старые данные из других процессов. Используйте allocUnsafe только тогда, когда вы сразу перезапишете всё содержимое.

Buffer и потоки

Потоки (stream.Readable, stream.Writable) по умолчанию передают данные как Buffer. Это основа для эффективной обработки больших файлов без загрузки всего содержимого в память:

import fs from 'fs';

const readable = fs.createReadStream('big-file.bin');

readable.on('data', (chunk: Buffer) => {
  // chunk — это Buffer, обрабатываем порционно
  console.log(`Получено ${chunk.length} байт`);
});

Размер буфера и ограничения

Максимальный размер одного Buffer ограничен константой buffer.constants.MAX_LENGTH (обычно ~2 ГБ на 64-битных системах). Создание очень больших буферов может вызвать ошибку ERR_INVALID_ARG_VALUE.

Что хочет услышать интервьюер

Понимание того, что Buffer хранится вне кучи V8 и работает с сырыми байтами

Знание разницы между Buffer.alloc и Buffer.allocUnsafe (безопасность vs производительность)

Понимание связи Buffer с потоками (Streams) и файловой системой

Знание основных кодировок (utf-8, hex, base64) и метода toString

Понимание того, что Buffer наследуется от Uint8Array и совместим с TypedArray

Пример: Создание и преобразование Buffer

// Создание Buffer разными способами
const fromString = Buffer.from('Привет, мир!', 'utf-8');
console.log(fromString.length); // 23 байта, не 12 символов (кириллица — 2 байта/символ)

const fromHex = Buffer.from('deadbeef', 'hex');
console.log(fromHex); // <Buffer de ad be ef>

// Безопасное выделение (заполнено нулями)
const safe = Buffer.alloc(8);

// Небезопасное — быстрее, но требует немедленной записи
const unsafe = Buffer.allocUnsafe(8);
unsafe.writeDoubleBE(3.14, 0); // сразу перезаписываем содержимое

// Конкатенация
const part1 = Buffer.from('Hello');
const part2 = Buffer.from(' World');
const combined = Buffer.concat([part1, part2]);
console.log(combined.toString()); // Hello World

// Преобразование в разные кодировки
const data = Buffer.from('Node.js');
console.log(data.toString('base64')); // Tm9kZS5qcw==
console.log(data.toString('hex'));    // 4e6f64652e6a73

Пример: Работа с бинарными файлами через Buffer

import fs from 'fs/promises';

async function processFile(path: string): Promise<void> {
  // fs.readFile возвращает Buffer по умолчанию
  const buffer: Buffer = await fs.readFile(path);

  // Читаем первые 4 байта как magic number (например, PNG: 89 50 4e 47)
  const magic = buffer.readUInt32BE(0);
  console.log(`Magic bytes: 0x${magic.toString(16).toUpperCase()}`);

  // Получаем часть файла без копирования памяти
  const header = buffer.subarray(0, 8);
  console.log('Header:', header);

  // Конвертируем текстовую часть в строку
  const textPart = buffer.subarray(8).toString('utf-8');
  console.log('Content:', textPart);
}

processFile('./example.bin').catch(console.error);

Типичные ошибки

Путают Buffer.slice (возвращает view, разделяет память) с Buffer.copy или Buffer.subarray — изменение слайса меняет оригинал

Используют new Buffer() — этот конструктор устарел и удалён, нужно использовать Buffer.from/alloc/allocUnsafe

Не указывают кодировку при Buffer.from(string) и не понимают, что по умолчанию используется utf-8

Используют Buffer.allocUnsafe там, где данные могут быть переданы наружу, не перезаписав содержимое — потенциальная утечка памяти

Считают, что Buffer и строка взаимозаменяемы — не учитывают, что length у Buffer — это байты, а не символы

Лучшие курсы по теме

изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Node.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее