Как закрыть читаемый поток в 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.");
}
});
Но это не остановило бы процесс чтения ...
fs
модуля.close
не существует вStream.Readable
.stream.destroy()
readable.push(null) && readable.destroy();
Ответы:
Вызов
input.close()
. Этого нет в документации, ноhttps://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
явно выполняет свою работу :) На самом деле он делает что-то похожее на ваш
isEnded
.РЕДАКТИРОВАТЬ 2015-апр-19 На основе комментариев ниже, а также для уточнения и обновления:
lib/fs.js
он все еще работает> 1,5 года спустя.destroy()
предпочтительности звонка .fs
ReadStreams
s, а не для общегоReadable
Что касается общего решения: не похоже, что оно есть, по крайней мере, из моего понимания документации и беглого взгляда
_stream_readable.js
.Мое предложение было бы перевести ваш читаемый поток в приостановленный режим, по крайней мере, предотвращая дальнейшую обработку в вашем исходном источнике данных. Не забудьте
unpipe()
удалить всеdata
прослушиватели событий, чтобыpause()
фактически приостанавливать работу, как указано в документации.источник
destroy
вместо этого позвонить . По крайней мере, это то, что вызывается, если вы установите autoClose в true. Если посмотреть на исходный код (сегодня), различия минимальны (destroy
звонкиclose
), но это может измениться в будущемclose()
объекта Readable, есть ли решение «никогда»? Мой обмен данными всегда неполный ...readable
шаблонclose()
, а предоставить специфичный для класса способ сделать это (как в случаеfs
и, предположительно, в других классахReadable
)Изменить: хорошие новости! Начиная с Node.js, версия 8.0.0
readable.destroy
официально доступна: https://nodejs.org/api/stream.html#stream_readable_destroy_errorReadStream.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
не задокументирована (Node.js v0.12.2), но вы можете ознакомиться с исходным кодом на GitHub ( 5 октября 2012 г., фиксация ).destroy
Функция внутренне отметьтеReadStream
экземпляр как уничтоженные и вызываетclose
функцию , чтобы освободить файл.Вы можете прослушать событие закрытия, чтобы точно знать, когда файл закрыт. Событие окончания не будет срабатывать , если данные не будут полностью израсходованы.
Обратите внимание, что функции
destroy
(иclose
) относятся к fs.ReadStream . Это не часть общего "интерфейса" stream.readable .источник
error
если он никогда не читается. Помимо этого, единственная утечка, о которой я бы беспокоился, - это обработчики событий - опять же, я не уверен на 100% в этом, но мы могли бы быть в порядке, потому что в 2010 году Евангелие Исаакса действительно говорит, что обработчики удаляется, когда эмиттеры gc'd: groups.google.com/d/msg/nodejs/pXbJVo0NtaY/BxUmF_jp9LkJon('data')
сработает только один раз, поэтому их не будет.close()
, просто напомните кому-то еще.Сегодня в узле 10
readableStream.destroy()
это официальный способ закрыть читаемый поток
см. https://nodejs.org/api/stream.html#stream_readable_destroy_error
источник
Вы не можете. Нет задокументированного способа закрыть / выключить / прервать / уничтожить общий читаемый поток с Node 5.3.0. Это ограничение потоковой архитектуры узла.
Как объяснялось в других ответах здесь, существуют недокументированные хаки для конкретных реализаций Readable, предоставляемых Node, таких как fs.ReadStream . Однако это не общие решения для любого Readable.
Если кто-то сможет доказать, что я неправ, пожалуйста, сделайте это. Я хотел бы иметь возможность сделать то, что я говорю, невозможно, и был бы рад исправлению.
РЕДАКТИРОВАТЬ : Вот мой обходной путь: реализовать
.destroy()
для моего конвейера через сложную сериюunpipe()
вызовов. И после всей этой сложности он не во всех случаях работает должным образом .РЕДАКТИРОВАТЬ : Node v8.0.0 добавил
destroy()
api для читаемых потоков .источник
stream.pipeline
утверждается, что он обрабатывает «ошибки пересылки и должным образом очищает и обеспечивает обратный вызов, когда конвейер завершен». Это помогает?В версии,
4.*.*
добавление нулевого значения в поток вызоветEOF
сигнал.Из документации nodejs
Это сработало для меня после того, как я попробовал множество других вариантов на этой странице.
источник
Этот модуль уничтожения предназначен для обеспечения уничтожения потока, обрабатывая различные API-интерфейсы и ошибки Node.js. Прямо сейчас - один из лучших вариантов.
NB. С узла 10 вы можете использовать этот
.destroy
метод без дополнительных зависимостей.источник
Вы можете очистить и закрыть поток с помощью
yourstream.resume()
, что сбросит все в потоке и в конечном итоге закроет его.Из официальных документов :
var readable = getReadableStreamSomehow(); readable.resume(); readable.on('end', () => { console.log('got to the end, but did not read anything'); });
источник
'data'
прослушиватель событий, но мы заставили его проверять логическое значение,if (!ignoring) { ... }
чтобы он не обрабатывал данные, когда мы сливаем поток.ignoring = true; readable.resume();
'end'
в какой-то момент поток будет . Не все стримы это делают! (Например, поток, который отправляет дату каждую секунду, навсегда.)Это старый вопрос, но я тоже искал ответ и нашел лучший для своей реализации. И события,
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 ...
источник
.end