Bagaimana cara menutup aliran yang dapat dibaca di 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.");
}
});
Ini akan lebih baik daripada:
input.on('data', function(data) {
if (isEnded) { return; }
if (gotFirstLine) {
isEnded = true;
console.log("Closed.");
}
});
Tetapi ini tidak akan menghentikan proses membaca ...
fs
modul.close
tidak ada diStream.Readable
.stream.destroy()
readable.push(null) && readable.destroy();
Jawaban:
Panggil
input.close()
. Ini tidak ada di dokumen, tapihttps://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
jelas melakukan pekerjaan itu :) Ini sebenarnya melakukan sesuatu yang mirip dengan Anda
isEnded
.EDIT 2015-Apr-19 Berdasarkan komentar di bawah, dan untuk memperjelas dan memperbarui:
lib/fs.js
ini masih berfungsi> 1,5 tahun kemudian.destroy()
yang lebih disukai.fs
ReadStreams
's, bukan pada generikReadable
Adapun solusi umum: tampaknya tidak ada, setidaknya dari pemahaman saya tentang dokumentasi dan dari pandangan sekilas
_stream_readable.js
.Proposal saya akan membuat streaming Anda yang dapat dibaca dalam mode dijeda , setidaknya mencegah pemrosesan lebih lanjut di sumber data upstream Anda. Jangan lupa untuk
unpipe()
menghapus semuadata
event listener sehinggapause()
benar - benar berhenti, seperti yang disebutkan dalam dokumensumber
destroy
. Setidaknya itulah yang disebut jika Anda menyetel autoClose ke true. Dengan melihat kode sumber (hari ini) perbedaannya minimal (destroy
panggilanclose
) tetapi itu bisa berubah di masa depanclose()
on object Readable, apakah tidak pernah ada solusi? Pertukaran data saya selalu tidak lengkap ...Edit: Kabar baik! Dimulai dengan Node.js 8.0.0
readable.destroy
secara resmi tersedia: https://nodejs.org/api/stream.html#stream_readable_destroy_errorReadStream.destroy
Anda dapat memanggil fungsi ReadStream.destroy kapan saja.
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'); });
Fungsi publik
ReadStream.destroy
tidak didokumentasikan (Node.js v0.12.2) tetapi Anda dapat melihat kode sumber di GitHub ( komit 5 Oktober 2012 ).The
destroy
fungsi internal menandaiReadStream
misalnya sebagai hancur dan memanggilclose
fungsi untuk melepaskan file.Anda dapat mendengarkan event close untuk mengetahui dengan tepat kapan file tersebut ditutup. Peristiwa akhir tidak akan diaktifkan kecuali data dikonsumsi sepenuhnya.
Perhatikan bahwa fungsi
destroy
(danclose
) khusus untuk fs.ReadStream . Tidak ada bagian dari "antarmuka" stream.readable generik .sumber
error
jika tidak pernah dibaca. Selain itu, satu-satunya kebocoran lain yang saya khawatirkan adalah penangan acara-- sekali lagi, saya tidak 100% yakin akan hal ini, tapi kita mungkin baik-baik saja karena Injil Isaacs tahun 2010 mengatakan bahwa penangannya adalah dipangkas ketika emitter di-gc'd: groups.google.com/d/msg/nodejs/pXbJVo0NtaY/BxUmF_jp9LkJon('data')
hanya akan terpicu sekali, jadi tidak akan ada.close()
, ingatkan saja orang lain.Hari ini, di Node 10
readableStream.destroy()
adalah cara resmi untuk menutup aliran yang dapat dibaca
lihat https://nodejs.org/api/stream.html#stream_readable_destroy_error
sumber
Tidak boleh. Tidak ada cara yang terdokumentasi untuk menutup / mematikan / membatalkan / menghancurkan aliran Readable generik pada Node 5.3.0. Ini adalah batasan dari arsitektur aliran Node.
Seperti jawaban lain yang dijelaskan di sini, ada peretasan tidak berdokumen untuk implementasi spesifik dari Readable yang disediakan oleh Node, seperti fs.ReadStream . Ini bukan solusi umum untuk semua Readable.
Jika seseorang bisa membuktikan saya salah di sini, tolong lakukan. Saya ingin dapat melakukan apa yang saya katakan tidak mungkin, dan dengan senang hati akan dikoreksi.
EDIT : Inilah solusi saya: terapkan
.destroy()
untuk pipeline saya melalui serangkaianunpipe()
panggilan yang rumit . Dan setelah semua kerumitan itu, itu tidak berfungsi dengan baik di semua kasus .EDIT : Node v8.0.0 menambahkan
destroy()
api untuk aliran yang Dapat Dibaca .sumber
stream.pipeline
, yang mengklaim menangani "kesalahan penerusan dan pembersihan yang benar serta memberikan callback saat pipeline selesai". Apakah itu membantu?Pada versi yang
4.*.*
mendorong nilai null ke dalam aliran akan memicuEOF
sinyal.Dari dokumen nodejs
Ini berhasil untuk saya setelah mencoba berbagai opsi lain di halaman ini.
sumber
Ini menghancurkan modul dimaksudkan untuk memastikan aliran akan hancur, penanganan API yang berbeda dan bug Node.js. Saat ini adalah salah satu pilihan terbaik.
NB. Dari Node 10 Anda dapat menggunakan
.destroy
metode ini tanpa ketergantungan lebih lanjut.sumber
Anda dapat menghapus dan menutup aliran dengan
yourstream.resume()
, yang akan membuang semua yang ada di aliran dan akhirnya menutupnya.Dari dokumen resmi :
var readable = getReadableStreamSomehow(); readable.resume(); readable.on('end', () => { console.log('got to the end, but did not read anything'); });
sumber
'data'
pendengar acara, tetapi kami membuatnya memeriksa booleanif (!ignoring) { ... }
sehingga tidak akan memproses data saat kami menguras aliran.ignoring = true; readable.resume();
'end'
di beberapa titik. Tidak semua aliran bisa melakukannya! (Misalnya aliran yang mengirimkan tanggal setiap detik, selamanya.)Ini pertanyaan lama tapi saya juga sedang mencari jawabannya dan menemukan yang terbaik untuk implementasi saya. Keduanya
end
danclose
acara dipancarkan jadi saya pikir ini adalah solusi terbersih.Ini akan melakukan trik di node 4.4. * (Versi stabil pada saat penulisan):
var input = fs.createReadStream('lines.txt'); input.on('data', function(data) { if (gotFirstLine) { this.end(); // Simple isn't it? console.log("Closed."); } });
Untuk penjelasan yang sangat rinci lihat: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm
sumber
Kode ini di sini akan melakukan trik dengan baik:
function closeReadStream(stream) { if (!stream) return; if (stream.close) stream.close(); else if (stream.destroy) stream.destroy(); }
writeStream.end () adalah cara masuk untuk menutup writeStream ...
sumber
.end