Padrões Readable & Writable
Streams Readable e Writable compartilham modos e primitivas de controle de fluxo - escolha o modo byte vs objeto antecipadamente e combine os tamanhos dos chunks do produtor com a taxa de transferência do consumidor.
Busque em todas as páginas da documentação
Streams Readable e Writable compartilham modos e primitivas de controle de fluxo - escolha o modo byte vs objeto antecipadamente e combine os tamanhos dos chunks do produtor com a taxa de transferência do consumidor.
import { Readable, Writable } from 'node:stream';
// Modo byte (padrão)
const byteStream = Readable.from([Buffer.from('ab'), Buffer.from('cd')]);
// Modo objeto
const objectStream = Readable.from([{ id: 1 }, { id: 2 }], { objectMode: true });Quando usar isso:
highWaterMark para memória vs latênciaReadable customizado a partir de uma fonte de dados assíncronaimport { Readable, Writable } from 'node:stream';
class CounterSource extends Readable {
private i = 0;
constructor(private max: number, opts?: ConstructorParameters<typeof Readable>[0]) {
super({ objectMode: true, ...opts });
}
_read(): void {
if (this.i >= this.max) {
this.push(null);
return;
}
this.push({ n: this.i++ });
}
}
const batchWriter = new Writable({
objectMode: true,
write(obj: { n: number }, _enc, cb) {
// simula inserção em lote no DB
setImmediate(cb);
},
});
const source = new CounterSource(1000);
source.pipe(batchWriter);// Modo pausado - read() explícito
const r = Readable.from(['a', 'b', 'c']);
r.on('readable', () => {
let chunk;
while ((chunk = r.read()) !== null) {
console.log(chunk);
}
});O que isso demonstra:
Readable customizado implementa _read e faz push até null encerrar o streamWritable em modo objeto recebe objetos tipados - agrupe em _write ou acumule para inserção em massareadable + read() - útil para analisar framingdata event ou pipe) é o padrão para a maioria das I/Osdata ou pipe.read(n) para puxar chunks.highWaterMark - limite do buffer interno; exceder dispara backpressure (false de write).cork/uncork no Writable agrupa pequenas escritas em menos chamadas de sistema.| Modo | Tipo de Chunk | Unidade highWaterMark | Uso Típico |
|---|---|---|---|
| Byte (padrão) | Buffer/string | bytes | Arquivos, HTTP, gzip |
| objectMode | qualquer valor JS | contagem de objetos | Registros, eventos |
import { Readable } from 'node:stream';
function linesFromFile(path: string): Readable {
return Readable.from(
(async function* () {
const { createReadStream } = await import('node:fs');
const { createInterface } = await import('node:readline');
const rl = createInterface({ input: createReadStream(path) });
for await (const line of rl) yield line;
})(),
);
}null - lança erro. Correção: rastrear estado de finalização em Readable customizado.false de write - estouro de memória. Correção: aguardar o evento drain.highWaterMark minúsculo em I/O de alta latência - sobrecarga de chamada de sistema. Correção: benchmark de 16-64 KB para arquivos.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
for await em iterável assíncrono | Consumo simples | Precisa de backpressure para desacelerar o disco |
Interface readline | Texto baseado em linha | Protocolos binários |
| Chunks EventEmitter | Código legado | Pipelines Greenfield |
| Web ReadableStream | Interoperabilidade com corpo do fetch | Caminho puramente node:fs |
16 KiB para streams de byte, 16 objetos para modo objeto - ajuste por carga de trabalho.
Quando você precisa de controle preciso sobre a taxa de consumo ou leituras parciais para framing.
Sim - um _write síncrono longo bloqueia o event loop - descarregue ou use worker threads.
Hook do Writable após o último chunk - descarrega buffers, completa trabalho assíncrono antes do evento finish.
Ambos os lados devem usar objectMode ou um Transform entre os mundos byte e objeto.
from para iteráveis; herde quando a fonte de pull precisar de lógica _read com estado.
Produz chunks de string em vez de Buffers - combine com as expectativas downstream.
Desmontagem abrupta com erro opcional - pipeline chama em caminhos de falha.
Lados de leitura/escrita independentes - sockets TCP - veja Transform & Duplex.
Use o padrão tee ou branches PassThrough - nunca faça double-pipe de um readable sem divisão.
Chame cb() quando terminar - ou retorne Promise de _write em variantes modernas da API de stream.
response.body é um Web ReadableStream - converta com Readable.fromWeb quando necessário.
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, e NestJS 11.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026