Как закрыть читаемый поток (до конца)?


Как закрыть a читаемый поток в узел.Джей?

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.");
   }
});

Это было бы лучше:

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

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

но это не остановит процесс чтения...

9 65

9 ответов:

Invoke input.close(). Это не в документах, но

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

явно делает работу :) он на самом деле делает что-то похожее на ваш isEnded.

EDIT 2015-Apr-19 на основе комментариев ниже, а также для уточнения и обновления:

  • это предложение является Хак, и не задокументировано.
  • хотя для того, чтобы смотреть на текущий lib/fs.js Он все еще работает >1.5 года спустя.
  • я согласен с комментарием ниже о вызове destroy() быть предпочтительнее.
  • как правильно указано ниже, это работает для fsReadStreams ' s, а не на общий Readable

что касается общего решения: похоже, что оно не существует, по крайней мере, из моего понимания документации и быстрого взгляда на _stream_readable.js.

мое предложение было бы положить ваш читаемый поток в пауза режим, по крайней мере предотвращающий дальнейшую обработку в вышестоящем источнике данных. Не забудьте unpipe() и удалить все data прослушиватели событий, так что pause() на самом деле паузы, как уже упоминалось в документы

ReadStream.уничтожить

вы можете позвонить в ReadStream.уничтожить в любое время.

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');
    });

общественная функция ReadStream.destroy не задокументирован (узел.js v0. 12. 2) но вы можете посмотреть на исходный код на GitHub (Oct 5, 2012 commit).

The

вы не можете. Не существует официальных документов, чтобы закрыть/завершить/отменить/уничтожить общего читабельный поток с узла 5.3.0. Это ограничение архитектуры потока узлов.

Как объяснили другие ответы здесь, есть недокументированные хаки для конкретных реализаций чтения, предоставляемых узлом, таких как fs.ReadStream. Это не общие решения для любого читаемого, хотя.

Если кто-то может доказать, что я ошибаюсь здесь, пожалуйста. Я хотел бы иметь возможность делать то, что я говорю, невозможно, и был бы рад быть исправленным.

EDIT: вот мое решение: реализовать .destroy() для моего конвейера, хотя сложная серия unpipe() звонки. и после всей этой сложности, это не работает должным образом во всех случаях.

по версии 4.*.* нажатие нулевого значения в поток вызовет EOF сигнал.

С nodejs docs

Если передается значение, отличное от null, метод push() добавляет фрагмент данных в очередь для последующего использования потоковыми процессорами. Если передается null, он сигнализирует конец потока (EOF), после чего больше не может быть записано никаких данных.

это сработало для меня после попытки многочисленных других параметры на этой странице.

сегодня, в узле 10

readableStream.destroy()

это официальный способ закрыть читаемый поток

см.https://nodejs.org/api/stream.html#stream_readable_destroy_error

Вы можете очистить и закрыть поток с yourstream.resume(), который будет сбрасывать все на поток и в конечном итоге закрыть его.

С официальные документы:

читаем.резюме():

Return: this

этот метод приведет к тому, что читаемый поток возобновит излучение событий "данных".

этот метод переключит поток в проточный режим. Если вы не хотите использовать данные из потока, но вы хотите, чтобы добраться до его "конец" события, вы можете вызвать поток.возобновить (), чтобы открыть поток данных.

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
  console.log('got to the end, but did not read anything');
});

Это старый вопрос, но я тоже искал ответ и нашел лучший для моей реализации. Оба end и close события испускаются, поэтому я думаю, что это самое чистое решение.

Это будет делать трюк в узел 4.4.* (стабильная версия на момент написания):

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

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

для очень подробного объяснения см.: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm

этот код будет делать трюк красиво:

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

writeStream.end ()-это способ закрыть writeStream...

этой уничтожить модуль предназначен для обеспечения уничтожения потока, обработки различных API и узла.в JS ошибки. Прямо сейчас является одним из лучших вариантов.