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.");
}
});
しかし、これは読み取りプロセスを停止しません...
input.close()
を呼び出します。ドキュメントにはありませんが、
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L162
明らかに仕事をします:)実際にあなたのisEnded
に似た何かをします。
EDIT 2015-Apr-19以下のコメントに基づき、明確化および更新するため:
lib/fs.js
を見ると、1.5年以上後でも動作します。destroy()
の呼び出しが望ましいという以下のコメントに同意します。fs
ReadStreams
に対して機能しますが、汎用のReadable
では機能しません一般的な解決策に関しては、少なくともドキュメントの理解と_stream_readable.js
のクイックルックからは、それが存在するようには見えません。
私の提案では、読み取り可能なストリームをpausedモードにし、少なくともアップストリームデータソースでのさらなる処理を防ぎます。 ドキュメント で説明されているように、unpipe()
を忘れずにdata
イベントリスナーをすべて削除して、pause()
が実際に一時停止するようにしてください。
編集:良いニュース! Node.js 8.0.0以降、readable.destroy
が正式に利用可能になりました: https://nodejs.org/api/stream.html#stream_readable_destroy_error
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のソースコード ( Oct 5、2012 commit =)。
destroy
関数は内部でReadStream
インスタンスを破棄済みとしてマークし、close
関数を呼び出してファイルを解放します。
close event をリッスンして、ファイルがいつ閉じられたかを正確に知ることができます。 end event は、データが完全に消費されない限り起動しません。
destroy
(およびclose
)関数は fs.ReadStream に固有であることに注意してください。ジェネリック stream.readable "interface"の一部はありません。
今日、Node 10
readableStream.destroy()
読み取り可能なストリームを閉じる公式の方法です
https://nodejs.org/api/stream.html#stream_readable_destroy_error を参照してください
できません。 Node 5.3.0の時点で、一般的な Readable ストリームを閉じる、シャットダウン、中止、破棄する文書化された方法はありません。これは、Nodeストリームアーキテクチャの制限です。
ここでの他の回答で説明したように、Nodeが提供するReadableの特定の実装( fs.ReadStream など)について文書化されていないハックがあります。ただし、これらはReadableの一般的なソリューションではありません。
ここで誰かが間違っていることを証明できる場合は、してください。私は不可能だと言っていることをできるようになりたいし、修正されることを喜んでいるだろう。
編集:ここに私の回避策がありました: 実装.destroy()
複雑な一連のunpipe()
呼び出し。 そして、すべてのその複雑さの後に、それは- すべての場合に正しく動作しません 。
編集:Node v8.0.0が追加されました destroy()
読み取り可能なストリームのAPI 。
バージョン4.*.*
では、null値をストリームにプッシュすると、EOF
シグナルがトリガーされます。
nodejs docs から
Null以外の値が渡された場合、Push()メソッドは、後続のストリームプロセッサが消費するデータのチャンクをキューに追加します。 nullが渡された場合、ストリームの終わり(EOF)を通知し、その後データを書き込むことはできません。
このページで他の多くのオプションを試した後、これはうまくいきました。
この destroy モジュールは、ストリームが確実に破棄され、さまざまなAPIとNode.jsのバグを処理することを目的としています。今は最良の選択の一つです。
NB。Node 10から、.destroy
メソッドをさらに依存関係なしで使用できます。
それは古い質問ですが、私も答えを探していて、私の実装に最適なものを見つけました。 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
yourstream.resume()
を使用してストリームをクリアして閉じることができます。これにより、ストリーム上のすべてがダンプされ、最終的には閉じられます。
公式ドキュメント から:
readable.resume():
戻り値:これ
このメソッドにより、読み取り可能なストリームが「データ」イベントの発行を再開します。
このメソッドは、ストリームをフローモードに切り替えます。ストリームからデータを消費したくないが、その「終了」イベントに到達したい場合は、stream.resume()を呼び出してデータのフローを開くことができます。
var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
console.log('got to the end, but did not read anything');
});
ここのこのコードはうまくトリックをします:
function closeReadStream(stream) {
if (!stream) return;
if (stream.close) stream.close();
else if (stream.destroy) stream.destroy();
}
writeStream.end()は、writeStreamを閉じる方法です...