¿Cómo cerrar un flujo legible (antes de finalizar)?


Cómo cerrar un flujo legible en el nodo.js?

var input = fs.createReadStream('lines.txt');

input.on('data', function(data) {
   // after closing the stream, this will not
   // be called again

   if (gotFirstLine) {
      // close this stream and continue the
      // instructions from this if
      console.log("Closed.");
   }
});

Esto sería mejor que:

input.on('data', function(data) {
   if (isEnded) { return; }

   if (gotFirstLine) {
      isEnded = true;
      console.log("Closed.");
   }
});

Pero esto no detendría el proceso de lectura...

Author: Yves M., 2013-10-09

9 answers

Invoca input.close(). No está en los documentos, pero

Https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620

Claramente hace el trabajo :) En realidad hace algo similar a su isEnded.

EDITAR 2015-Apr-19 Basado en los comentarios a continuación, y para aclarar y actualizar:

  • Esta sugerencia es un hack, y no está documentada.
  • Aunque para mirar la corriente lib/fs.js todavía funciona >1.5 años tarde.
  • Estoy de acuerdo con el comentario a continuación acerca de llamar destroy() es preferible.
  • Como se indica correctamente a continuación, esto funciona para fs ReadStreams's, no en un genérico Readable

En cuanto a una solución genérica: no parece que haya una, al menos desde mi comprensión de la documentación y de un vistazo rápido a _stream_readable.js.

Mi propuesta sería poner su flujo legible en modo pausado , al menos evitando el procesamiento posterior en sus datos ascendentes fuente. No olvides unpipe() y eliminar todos los oyentes de eventos data para que pause() realmente se detenga, como se menciona en los documentos

 29
Author: Nitzan Shaked,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-22 17:49:42

ReadStream.destruir

Puede llamar al flujo de lectura .destruye la función en cualquier momento.

var fs = require('fs');

var readStream = fs.createReadStream('lines.txt');
readStream
    .on('data', function (chunk) {
        console.log(chunk);
        readStream.destroy();
    })
    .on('end', function () {
        // This may not been called since we are destroying the stream
        // the first time 'data' event is received
        console.log('All the data in the file has been read');
    })
    .on('close', function (err) {
        console.log('Stream has been destroyed and file has been closed');
    });

La función pública ReadStream.destroy no está documentada (Nodo.js v0. 12. 2) pero puedes echar un vistazo al código fuente en GitHub (Oct 5, 2012 commit ).

La función destroy marca internamente la instancia ReadStream como destruida y llama a la función close para liberar el archivo.

Puedes escuchar el evento close para saber exactamente cuándo el archivo está cerrado. El evento end no se disparará a menos que los datos se consuman por completo.


Tenga en cuenta que las funciones destroy (y close) son específicas de fs.ReadStream . No hay parte de la corriente genérica .legible "interfaz".

 42
Author: Yves M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-23 08:16:43

No se puede. No hay una forma documentada de cerrar/apagar/abortar/destruir un flujo genérico legible a partir del nodo 5.3.0. Esta es una limitación de la arquitectura de flujo de nodos.

Como han explicado otras respuestas aquí, hay hacks no documentados para implementaciones específicas de Legible proporcionadas por Node, como fs.ReadStream . Estas no son soluciones genéricas para cualquier Legible sin embargo.

Si alguien puede probar que estoy equivocado aquí, por favor hágalo. Me gustaría ser capaz de hacer lo que estoy diciendo es imposible, y estaría encantado de ser corregido.

EDITAR : Aquí estaba mi solución: implementar .destroy() para mi canalización a través de una serie compleja de llamadas unpipe(). Y después de toda esa complejidad, no funciona correctamente en todos los casos.

 11
Author: thejoshwolfe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-06 18:59:58

En la versión 4.*.* empujar un valor null en la secuencia activará una señal EOF.

Del nodejs docs

Si se pasa un valor que no sea null, el método push() agrega un trozo de datos a la cola para que los procesadores de flujo posteriores lo consuman. Si se pasa null, señala el final de la secuencia (EOF), después de lo cual no se pueden escribir más datos.

Esto funcionó para mí después de probar muchas otras opciones en esta página.

 9
Author: Jacob Lowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-21 06:19:00

Hoy, en el Nodo 10

readableStream.destroy()

Es la forma oficial de cerrar un flujo legible

Véase https://nodejs.org/api/stream.html#stream_readable_destroy_error

 6
Author: Jo Takion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-03 12:40:08

Puede borrar y cerrar la corriente con yourstream.resume(), lo que volcará todo en la corriente y eventualmente la cerrará.

De los documentos oficiales :

Legible.resume ():

Return: this

Este método hará que el flujo legible reanude la emisión de eventos 'data'.

Este método cambiará la corriente al modo de flujo. Si no desea consumir los datos de un flujo, pero desea llegar a su evento 'fin', puede llama a stream.resume () para abrir el flujo de datos.

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
  console.log('got to the end, but did not read anything');
});
 3
Author: Sayem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-04 13:33:42

Es una pregunta antigua, pero yo también estaba buscando la respuesta y encontré la mejor para mi implementación. Ambos eventos end y close se emiten así que creo que esta es la solución más limpia.

Esto hará el truco en el nodo 4.4.* (versión estable en el momento de escribir):

var input = fs.createReadStream('lines.txt');

input.on('data', function(data) {
   if (gotFirstLine) {
      this.end(); // Simple isn't it?
      console.log("Closed.");
   }
});

Para una explicación muy detallada ver: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm

 3
Author: Vexter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-07 14:39:11

Este código aquí hará el truco muy bien:

function closeReadStream(stream) {
    if (!stream) return;
    if (stream.close) stream.close();
    else if (stream.destroy) stream.destroy();
}

WriteStream.end() es la forma de cerrar un WriteStream...

 2
Author: g00dnatur3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-02 05:12:56

Este módulo destroy está destinado a garantizar que una secuencia se destruya, manejando diferentes API y Nodos.js bugs. Ahora mismo es una de las mejores opciones.

 2
Author: Rocco Musolino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-10 18:44:19