Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

385
Visualizações
Escrituras en búfer en stdout en node.js

En node.js, se documenta que el flujo process.stdout se comporta "sincrónicamente", lo que, entre otras cosas, significa que cada llamada a stdout.write provoca una llamada al sistema de write inmediata, no hay almacenamiento en búfer. Por ejemplo

 import { stdout } from 'process'; for (let i = 1; i <= 1000; i++) { stdout.write(`line ${i}\n`); } stdout.end();

hace 1000 llamadas al sistema de write . Esto no es lo que desea cuando está escribiendo una utilidad de emisión de datos tradicional de Unix. Es posible omitir process.stdout y crear una secuencia de escritura separada que se hunda en el descriptor de archivo 1, por ejemplo

 import { stdout } from 'process'; import { createWriteStream } from 'fs'; let ostream = createWriteStream("/ignored", { fd: stdout.fd }); for (let i = 1; i <= 1000; i++) { ostream.write(`line ${i}\n`); } ostream.end();

hace una sola llamada al sistema. Sin embargo, los desvíos como este son peligrosos: después de la llamada ostream.end , el descriptor de archivo 1 se cierra pero el objeto process.stdout no lo sabe.

¿Hay alguna forma oficial de obtener una salida almacenada en búfer cuando se usa process.stdout ? Ideal en mi libro sería algo como el setvbuf de C.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

También puede llamar a .end() en stdout. No estoy seguro de si esto lo hace más seguro.

 import { promisify } from 'util'; import stream from 'stream'; import { stdout } from 'process'; import { createWriteStream } from 'fs'; const finished = promisify(stream.finished); let ostream = createWriteStream("/ignored", { fd: stdout.fd }); for (let i = 1; i <= 1000; i++) { ostream.write(`line ${i}\n`); } ostream.end(); await finished(ostream).then(()=> { console.log('Not quite done.'); stdout.end() console.log('Not gonna see this.'); });

EDITAR: acabo de leer en los documentos de Node que en los sistemas POSIX, si usa tuberías para enviar datos a la salida estándar, es asíncrono. Así que el siguiente código debería funcionar:

 import { stdout } from 'process'; import { Readable } from 'stream'; const data = new Readable() data._read = () => {}; data.pipe(stdout); for (let i = 1; i <= 1000; i++) { data.push(`line ${i}\n`); }
over 4 years ago · Santiago Trujillo Relatório

0

Utilice process.stdout.cork()

El método writable.cork() obliga a que todos los datos escritos se almacenen en la memoria. Los datos almacenados en el búfer se eliminarán cuando se llame a los métodos stream.uncork() o stream.end().

Nota: esto también console.log() .

 process.stdout.cork(); for (let i = 1; i <= 1000; i++) { process.stdout.write(`line ${i}\n`); } process.stdout.uncork();

O, si desea vaciar el búfer cada vez que se alcanza el ciclo de eventos, puede anular write() :

 const { stdout } = process; const { write } = stdout; stdout.write = function() { if (this.writableCorked == 0) { this.cork(); process.nextTick(() => this.uncork()); } write.apply(this, arguments); } for (let i = 1; i <= 1000; i++) { process.stdout.write(`line ${i}\n`); }

Si le preocupa que el búfer se vuelva demasiado grande, también puede consultar stdout.writableNeedDrain .

strace -f -c -e trace=write,writev resultados:

 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000006 1 4 write 0.00 0.000000 0 1 writev ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000006 5 total

Probado usando el nodo v16.13.2

over 4 years ago · Santiago Trujillo Relatório

0

Después de pensar un poco más en esto, la forma ideal de configurar el uso de process.stdout de manera segura y eficiente para la salida de datos masivos sería STDOUT_FILENO dup envolver un fs.WriteStream normal alrededor del duplicado y luego dup2 STDERR_FILENO sobre STDOUT_FILENO , lo que haría que todos los métodos del objeto de consola global y process.stdout escribieran en stderr en lugar de stdout. (Por lo que puedo decir, no hay otra forma de hacerlo). El código que genera los datos masivos luego escribiría en WriteStream normal en lugar de procesar.stdout.

O, en código:

 import * as fs from "fs/promises"; import process from "process"; async function prepare_buffered_stdout(options) { options ??= {}; const stdout_copy = await fs.dup(process.stdout.fd); await fs.dup2(process.stderr.fd, process.stdout.fd); return fs.fdopen(stdout_copy, "w").createWriteStream(options); }

Desafortunadamente, existe el problema menor de que las funciones fs.dup , fs.dup2 y fs.fdopen no existen. He presentado una solicitud de función para que se agreguen .

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda