Подтвердить что ты не робот

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

Как закрыть читаемый поток в Node.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.");
   }
});

Это будет лучше, чем:

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

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

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

4b9b3361

Ответ 1

Вызвать input.close(). Это не в документах, но

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

четко выполняет задание:) На самом деле это что-то похожее на ваш isEnded.

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

  • Это предложение является взломом и не документировано.
  • Хотя для просмотра текущего lib/fs.js он все еще работает > 1.5yrs позже.
  • Я согласен с комментарием ниже о предпочтительности вызова destroy().
  • Как правильно указано ниже, это работает для fs ReadStreams, а не для общего Readable

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

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

Ответ 2

Изменить: хорошие новости! Начиная с Node.js 8.0.0 официально доступен readable.destroy: https://nodejs.org/api/stream.html#stream_readable_destroy_error

ReadStream.destroy

Вы можете вызвать функцию ReadStream.destroy в любое время.

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 функция ReadStream.destroy не документирована (Node.js v0.12.2), но вы можете взглянуть на исходный код на GitHub (фиксация 5 октября 2012 г.).

Функция destroy внутренне ReadStream экземпляр ReadStream как уничтоженный и вызывает функцию close для освобождения файла.

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


Обратите внимание, что функции destroyclose) специфичны для fs.ReadStream. Не существует части общего интерфейса stream.readable.

Ответ 4

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

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

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

РЕДАКТИРОВАТЬ: Вот мой обходной путь: реализовать .destroy() для моего конвейера, хотя сложная серия unpipe(). И после всей этой сложности, это не работает должным образом во всех случаях.

РЕДАКТИРОВАТЬ: Node v8.0.0 добавил API destroy() для читаемых потоков.

Ответ 5

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

Из nodejs docs

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

Это сработало для меня, попробовав множество других опций на этой странице.

Ответ 6

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

NB. С узла 10 вы можете использовать метод .destroy без дополнительных зависимостей.

Ответ 7

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

Из официальных официальных документов:

readable.resume():

Возврат: this

Этот метод заставит читаемый поток возобновить выдачу событий "данных".

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

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

Ответ 8

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

Это сделает трюк в node 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

Ответ 9

Этот код здесь прекрасно подойдет:

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

writeStream.end() - это путь к закрытию writeStream...