Node.js: Buffers e Dados Binários

Última atualização: 2026-08-26

Ao desenvolver um serviço de envio de imagens, Bob percebeu que os arquivos JPEG enviados pelos usuários eram convertidos em uma sequência de caracteres ilegíveis após serem lidos pelo fs.readFile — as strings de JavaScript são armazenadas usando a codificação UTF-16, que não consegue representar corretamente todos os valores de byte entre 0x00 e 0xFF. Ele descobriu que o Node.js oferece um objeto global Buffer projetado especificamente para lidar com dados binários. Ele funciona como um bloco de memória bruta, em que cada posição corresponde exatamente a um único byte. Desde a leitura e gravação de arquivos até a transmissão em rede, e do processamento de imagens aos cálculos criptográficos, Buffer é a ferramenta central para o tratamento de dados binários no Node.js.

1. O que você vai aprender



2. O que é um buffer?

Um Buffer é um objeto global fornecido pelo Node.js, utilizado para alocar uma região de tamanho fixo de dados binários brutos fora do heap do V8. Cada elemento ocupa 1 byte (8 bits), com valores que variam de 0 a 255. Um Buffer não requer require e está pronto para uso imediato.

JAVASCRIPT
const buf = Buffer.alloc(4);
console.log(buf);
console.log(buf.length);
TEXT 📖 Somente leitura
<Buffer 00 00 00 00>
4
100%
flowchart LR
  subgraph Input["Input Source"]
    D[Disk Files]
    N[Network Request]
    C[Cryptographic Operations]
  end

  subgraph Core["Node.js Runtime"]
    B[Buffer<br/>Raw binary data]
    S[String / JSON<br/>Structured Data]
  end

  D -->|Binary Reading| B
  N -->|Raw bytes| B
  C -->|Hash/Signature| B
  B -->|toString / decode| S
  S -->|Buffer.from / encode| B
  B -->|Binary Writing| D
  B -->|Raw bytes| N


3. Como criar um buffer

O Node.js oferece várias maneiras de criar um Buffer, e cada método é adequado para diferentes cenários.

Método Conteúdo de inicialização Segurança Desempenho Casos de uso
Buffer.alloc(size) Preenchimento 0 Seguro Lento Requer um buffer novo e limpo
Buffer.allocUnsafe(size) Não inicializado (dados antigos) Não seguro Rápido Sensível ao desempenho e preenchido imediatamente
Buffer.from(array) Valor do elemento da matriz Segurança Geral Criado a partir de uma matriz de bytes
Buffer.from(string, encoding) Sequência codificada Segurança Geral Criar a partir de uma sequência
Buffer.from(buffer) Copiar o buffer de origem Segurança Geral Clonar o buffer

▶ Exemplo: alloc vs allocUnsafe

JAVASCRIPT
const safe = Buffer.alloc(8);
console.log('alloc:', safe);

const unsafe = Buffer.allocUnsafe(8);
console.log('allocUnsafe:', unsafe);
▶ Experimente
TEXT 📖 Somente leitura
alloc: <Buffer 00 00 00 00 00 00 00 00>
allocUnsafe: <Buffer a0 3f 1b 00 00 00 00 00>

▶ Exemplo: Criação a partir de matrizes e strings

JAVASCRIPT
const fromArr = Buffer.from([72, 101, 108, 108, 111]);
console.log('from array:', fromArr.toString());

const fromStr = Buffer.from('Hello', 'utf8');
console.log('from string:', fromStr.toString());

const fromHex = Buffer.from('48656c6c6f', 'hex');
console.log('from hex:', fromHex.toString());
▶ Experimente
TEXT 📖 Somente leitura
from array: Hello
from string: Hello
from hex: Hello


4. Codificação e decodificação

O Node.js suporta várias codificações de caracteres, e o Buffer pode converter livremente entre elas.

Código Descrição Bytes por caractere Usos típicos
utf8 Codificação Unicode de comprimento variável 1–4 Processamento de texto (codificação padrão)
ASCII ASCII de 7 bits 1 Texto em inglês simples
base64 Codificado em Base64 Aproximadamente 4/3 do original Incorporado em uma imagem, anexo de e-mail
hex Representação hexadecimal 2 Saída de depuração, exibição de hash
binário / latin1 Mapeamento direto de caracteres por byte 1 Operações byte a byte

▶ Exemplo: Conversão de codificação

JAVASCRIPT
const text = 'Node.js Buffer';

const utf8Buf = Buffer.from(text, 'utf8');
console.log('utf8 bytes:', utf8Buf.length);

const base64 = utf8Buf.toString('base64');
console.log('base64:', base64);

const hex = utf8Buf.toString('hex');
console.log('hex:', hex);

const decoded = Buffer.from(base64, 'base64').toString('utf8');
console.log('decoded:', decoded);
▶ Experimente
TEXT 📖 Somente leitura
utf8 bytes: 14
base64: Tm9kZS5qcyDliIbku6znqIvl
hex: 4e6f64652e6a7320e7bc93e586b2e58cba
decoded: Node.js Buffer

▶ Exemplo: Dados de imagem codificados em Base64

JAVASCRIPT
const fs = require('fs');

const imgBuf = fs.readFileSync('logo.png');
const dataUri = 'data:image/png;base64,' + imgBuf.toString('base64');
console.log('Data URI length:', dataUri.length);
▶ Experimente

5. Conversão entre buffer e string

A conversão entre Buffer e String é uma das operações mais comuns no dia a dia do desenvolvimento.

Direção Método Descrição
String → Buffer Buffer.from(str, encoding) A codificação padrão é utf8
Buffer → String buf.toString(encoding) A codificação padrão é utf8
Comprimento em bytes da string de consulta Buffer.byteLength(str, encoding) Retorna o número de bytes, e não de caracteres

▶ Exemplo: Número de caracteres x número de bytes

JAVASCRIPT
const str = 'Hello, World';
console.log('Number of characters:', str.length);
console.log('Number of bytes (utf8):', Buffer.byteLength(str, 'utf8'));
console.log('Number of bytes (ascii):', Buffer.byteLength(str, 'ascii'));

const buf = Buffer.from(str, 'utf8');
console.log('buf.length:', buf.length);
console.log('Restore the string:', buf.toString('utf8'));
▶ Experimente
TEXT 📖 Somente leitura
Number of characters: 4
Number of bytes (utf8): 12
Number of bytes (ascii): 4
buf.length: 12
Restore the string: Hello, World


6. Como usar o Buffer

(1) Tabela de referência rápida para métodos comuns de buffer

Método Finalidade Valor de retorno
Buffer.alloc(size, fill) Criar e preencher Novo buffer
Buffer.from(source, enc) Criar a partir do código-fonte Novo buffer
Buffer.concat(list, totalLen) Concatenar vários buffers Novo buffer
Buffer.isBuffer(obj) Verificar se é um buffer Valor booleano
Buffer.byteLength(str, enc) Comprimento da sequência em bytes Número
buf.slice(start, end) Visualização instantânea (memória compartilhada) Visualização do buffer
buf.subarray(start, end) A mesma fatia Visualização do buffer
buf.toString(enc) Converter para string string
buf.write(str, offset, enc) Gravar uma string no bufferー Número de bytes a serem gravados
buf.copy(target, tStart, sStart, sEnd) Copiar para o buffer de destino Número de bytes a serem copiados
buf.equals(otherBuf) Comparar se o conteúdo é o mesmo Valor booleano
buf.compare(otherBuf) Comparação lexicográfica -1 / 0 / 1
buf.fill(value, start, end) Preencher intervalo especificado Buffer original
buf.indexOf(value, byteOffset) Localizar posição de byte Número

▶ Exemplo: concat – concatenação

JAVASCRIPT
const part1 = Buffer.from('Hello, ');
const part2 = Buffer.from('Buffer!');
const merged = Buffer.concat([part1, part2]);
console.log(merged.toString());
console.log('total length:', merged.length);
▶ Experimente
TEXT 📖 Somente leitura
Hello, Buffer!
total length: 14

▶ Exemplo: Visualizações de fatia e compartilhamento de memória

JAVASCRIPT
const original = Buffer.from('ABCDEFGH');
const sliced = original.slice(0, 4);

sliced[0] = 88;
console.log('original:', original.toString());
console.log('sliced:', sliced.toString());
▶ Experimente
TEXT 📖 Somente leitura
original: XBCDEFGH
sliced: XBCD

▶ Exemplo: escrever e copiar

JAVASCRIPT
const buf = Buffer.alloc(16);
buf.write('Hi', 0, 'utf8');
buf.write('There', 2, 'utf8');
console.log('after write:', buf.toString('utf8', 0, 7));

const src = Buffer.from('COPY');
const dest = Buffer.alloc(8);
src.copy(dest, 2);
console.log('after copy:', dest.toString());
▶ Experimente
TEXT 📖 Somente leitura
after write: HiThere
after copy:   COPY


7. Buffer e TypedArray

A memória subjacente de Buffer compartilha o mesmo mecanismo ArrayBuffer que o TypedArray do ES2015. Buffer é essencialmente uma subclasse de Uint8Array, mas possui métodos adicionais específicos do Node.js.

Característica Buffer Uint8Array ArrayBuffer
Fonte Objeto global do Node.js Incorporado no ES2015 Incorporado no ES2015
Mecanismo subjacente Baseado em ArrayBuffer Baseado em ArrayBuffer Memória binária bruta
Ordem dos bytes Depende da plataforma Depende da plataforma Não há conceito de ordem dos bytes
Métodos proprietários toString/slice/concat, etc. Métodos padrão do TypedArray Apenas byteLength
Método de criação Buffer.alloc/Buffer.from new Uint8Array() new ArrayBuffer()
Compatibilidade entre módulos Pode ser passado para complementos em C++ Pode ser passado para APIs da Web Formato subjacente universal

▶ Exemplo: Conversão entre Buffer e Uint8Array

JAVASCRIPT
const buf = Buffer.from([1, 2, 3, 4, 5]);

const uint8 = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
console.log('Uint8Array:', uint8);

const backToBuf = Buffer.from(uint8.buffer);
console.log('Buffer:', backToBuf);
console.log('isBuffer:', Buffer.isBuffer(backToBuf));
▶ Experimente
TEXT 📖 Somente leitura
Uint8Array: Uint8Array(5) [1, 2, 3, 4, 5]
Buffer: <Buffer 01 02 03 04 05>
isBuffer: true

▶ Exemplo: Como ler valores multibyte usando o DataView

JAVASCRIPT
const buf = Buffer.alloc(4);
buf.writeUInt32BE(0x12345678, 0);
console.log('big-endian:', buf.toString('hex'));

const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
console.log('read as uint32:', view.getUint32(0, false));
console.log('read as uint16:', view.getUint16(0, false));
▶ Experimente
TEXT 📖 Somente leitura
big-endian: 12345678
read as uint32: 305419896
read as uint16: 4660


8. Leitura e gravação de arquivos binários

Ao usar fs.readFile para ler um arquivo sem especificar uma codificação, o valor retornado é um buffer, e não uma string. Essa é a abordagem padrão para lidar com arquivos binários, como imagens, áudio e vídeo.

▶ Exemplo: Como ler um arquivo binário

JAVASCRIPT
const fs = require('fs');

const imgBuf = fs.readFileSync('photo.jpg');
console.log('isBuffer:', Buffer.isBuffer(imgBuf));
console.log('size:', imgBuf.length, 'bytes');
console.log('first 8 bytes (hex):', imgBuf.slice(0, 8).toString('hex'));

const isJPEG = imgBuf[0] === 0xFF && imgBuf[1] === 0xD8;
const isPNG = imgBuf[0] === 0x89 && imgBuf[1] === 0x50;
console.log('isJPEG:', isJPEG);
console.log('isPNG:', isPNG);
▶ Experimente
TEXT 📖 Somente leitura
isBuffer: true
size: 245760 bytes
first 8 bytes (hex): ffd8ffe000104a46
isJPEG: true
isPNG: false

▶ Exemplo: Aplicações de buffers em redes e criptografia

JAVASCRIPT
const crypto = require('crypto');

const data = Buffer.from('important message', 'utf8');

const hash = crypto.createHash('sha256').update(data).digest();
console.log('sha256 (hex):', hash.toString('hex'));

const hmac = crypto.createHmac('sha256', 'secret-key').update(data).digest();
console.log('hmac (hex):', hmac.toString('hex'));

const randomBytes = crypto.randomBytes(16);
console.log('random (hex):', randomBytes.toString('hex'));
▶ Experimente
TEXT 📖 Somente leitura
sha256 (hex): 8c8821c72b56a55724e9ad64b875e4b62e6c5e9f9c4c4b0c4d5e6f7a8b9c0d1e
hmac (hex): a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
random (hex): 3a7f2b1c9d4e8a6f5b0c7d2e1f3a4b8c


9. Exemplo completo: Ferramenta de codificação de arquivos

Crie uma ferramenta simples de codificação de arquivos: leia um arquivo binário → converta para Base64 → grave em um arquivo de texto → decodifique para restaurar os dados originais.

(1) Comparação entre Buffer, String e TypedArray

Dimensão Buffer String TypedArray
Conteúdo armazenado Bytes brutos Ponto de código UTF-16 Valor específico do tipo
Tamanho do elemento Fixo em 1 byte 2 bytes (UTF-16) 1–8 bytes
Tipos de dados suportados Binário, Arquivos, Rede Texto Matrizes numéricas, WebGL
Mutável Modificável Imutável Modificável
Tratamento de bytes nulos Armazenamento normal Truncamento de strings Armazenamento normal
Suporte a codificação UTF-8/Base64/hex, etc. Apenas UTF-16 Não há conceito de codificação
JAVASCRIPT
const fs = require('fs');
const path = require('path');

function encodeFile(inputPath, outputPath) {
  const raw = fs.readFileSync(inputPath);
  const base64 = raw.toString('base64');
  fs.writeFileSync(outputPath, base64, 'utf8');
  console.log(`Encoded: ${raw.length} bytes → ${base64.length} chars`);
  return { originalSize: raw.length, encodedSize: base64.length };
}

function decodeFile(inputPath, outputPath) {
  const base64Str = fs.readFileSync(inputPath, 'utf8');
  const decoded = Buffer.from(base64Str, 'base64');
  fs.writeFileSync(outputPath, decoded);
  console.log(`Decoded: ${base64Str.length} chars → ${decoded.length} bytes`);
  return { encodedSize: base64Str.length, decodedSize: decoded.length };
}

function verify(originalPath, restoredPath) {
  const a = fs.readFileSync(originalPath);
  const b = fs.readFileSync(restoredPath);
  if (a.equals(b)) {
    console.log('Verification: PASSED - files are identical');
  } else {
    console.log('Verification: FAILED - files differ');
  }
}

const inputPath = path.join(__dirname, 'sample.dat');
const encodedPath = path.join(__dirname, 'sample.b64.txt');
const restoredPath = path.join(__dirname, 'sample.restored.dat');

const sampleData = Buffer.alloc(256);
for (let i = 0; i < 256; i++) {
  sampleData[i] = i;
}
fs.writeFileSync(inputPath, sampleData);

encodeFile(inputPath, encodedPath);
decodeFile(encodedPath, restoredPath);
verify(inputPath, restoredPath);
TEXT 📖 Somente leitura
Encoded: 256 bytes → 344 chars
Decoded: 344 chars → 256 bytes
Verification: PASSED - files are identical

❓ Perguntas Frequentes

P: Qual é a diferença entre Buffer.alloc e Buffer.allocUnsafe? R: Buffer.alloc(size) inicializa cada byte como 0; é seguro, mas um pouco mais lento. Buffer.allocUnsafe(size) não inicializa os bytes; eles podem conter dados antigos da memória. Oferece desempenho mais rápido, mas deve ser preenchido imediatamente; caso contrário, informações confidenciais podem vazar.

P: A função buf.length retorna o número de bytes ou o número de caracteres? R: A função buf.length retorna o número de bytes, ao contrário da função str.length para cadeias de caracteres (que retorna o número de unidades de código UTF-16). Por exemplo, o str.length de 'Olá' é 2, mas o Buffer.byteLength('Olá') é 6 (cada caractere chinês tem 3 bytes em UTF-8).

P: Por que não usar String para lidar com dados binários? R: As strings do JavaScript usam a codificação UTF-16, que não consegue representar corretamente o byte 0x00 (ele é truncado), e não há mapeamento direto entre caracteres multibyte e bytes. Cada posição em um Buffer corresponde exatamente a um byte, tornando-o o contêiner correto para dados binários.

P: O Buffer faz parte do JavaScript? R: Não. O Buffer é um objeto global específico do Node.js e não faz parte da especificação ECMAScript. Não existe Buffer no ambiente do navegador; em vez disso, ele é representado por APIs da Web, como Uint8Array e ArrayBuffer.

P: Como posso determinar se um value é um Buffer? R: Use Buffer.isBuffer(obj); ele retornará true ou false. Não use instanceof, pois pode falhar ao cruzar domínios (como módulos de VM diferentes).

P: Qual é a diferença entre buf.slice() e buf.subarray()? R: No Node.js, eles se comportam de maneira idêntica; ambos retornam visualizações que compartilham a memória subjacente. subarray foi adicionado para manter a consistência de nomenclatura com Uint8Array.プロトタイプ.subarray, enquanto slice foi mantido por motivos de compatibilidade com versões anteriores. Recomenda-se usar subarray em códigos novos.

P: Como posso converter um Buffer para JSON com segurança? R: Usar buf.toJSON() retornará um objeto no formato { type: 'Buffer', data: [...] }. Você também pode usar JSON.stringify(buf) diretamente, o que chamará automaticamente toJSON(). Após a desserialização, use Buffer.from(obj.data) para restaurar os dados originais.


📖 Resumo


📝 Exercícios

  1. Conclua todos os exemplos de código desta lição e certifique-se de que cada um deles seja executado corretamente.
  2. Modifique o exemplo completo e adicione suas próprias extensões
  3. Analise a documentação oficial, identifique 1 ou 2 APIs que não foram abordadas nesta aula e escreva um código de teste para elas.
  4. Reflexão: Como você aplicaria o que aprendeu nesta aula a um projeto do mundo real?
  5. Tente combinar o que você aprendeu nesta lição com o conteúdo das lições anteriores para criar um pequeno projeto.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%