Comment fermer un flux lisible dans 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.");
}
});
Ce serait mieux que:
input.on('data', function(data) {
if (isEnded) { return; }
if (gotFirstLine) {
isEnded = true;
console.log("Closed.");
}
});
Mais cela n'arrêterait pas le processus de lecture ...
Invoquez input.close()
. Ce n'est pas dans la documentation, mais
https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L162
fait clairement le travail :) Il fait en fait quelque chose de similaire à votre isEnded
.
EDITER 2015-avr-19 Basé sur les commentaires ci-dessous, et pour clarifier et mettre à jour:
lib/fs.js
Actuel, il fonctionne toujours> 1,5 ans plus tard.destroy()
étant préférable.fs
ReadStreams
, pas sur un générique Readable
.En ce qui concerne une solution générique: il ne semble pas qu'il en existe une, du moins d'après ma compréhension de la documentation et d'après un rapide coup d'œil à _stream_readable.js
.
Ma proposition mettrait votre flux lisible en mode en pause, empêchant au moins tout traitement ultérieur dans votre source de données en amont. N'oubliez pas de unpipe()
et supprimez tous les écouteurs d'événement data
afin que pause()
s'interrompt réellement, comme indiqué dans la documentation
Edit: Bonne nouvelle! Commençant par Node.js 8.0.0 readable.destroy
est officiellement disponible: https://nodejs.org/api/stream.html#stream_readable_destroy_error
Vous pouvez appeler la fonction ReadStream.destroy à tout moment.
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');
});
La fonction publique ReadStream.destroy
n'est pas documenté (Node.js v0.12.2) mais vous pouvez consulter le code source sur GitHub ( commit du 5 octobre 2012 ).
La fonction destroy
marque en interne l'instance ReadStream
comme détruite et appelle la fonction close
pour libérer le fichier.
Vous pouvez écouter le événement de fermeture pour savoir exactement quand le fichier est fermé. Le événement final ne se déclenchera que si les données sont complètement consommées.
Notez que les fonctions destroy
(et close
) sont spécifiques à fs.ReadStream . Il ne fait pas partie du générique stream.readable "interface".
Aujourd'hui, dans Node 10
readableStream.destroy()
est le moyen officiel de fermer un flux lisible
voir https://nodejs.org/api/stream.html#stream_readable_destroy_error
Tu ne peux pas. Il n’existe aucun moyen documenté de fermer/arrêter/abandonner/détruire un flux générique Lisible à partir de Node 5.3.0. Il s’agit d’une limitation du Node architecture de flux.
Comme d'autres réponses l'ont expliqué, il existe des méthodes informelles pour des implémentations spécifiques de Readable fournies par Node, telles que fs.ReadStream . Ce ne sont pas des solutions génériques pour tout lisible cependant.
Si quelqu'un peut me prouver le contraire, faites-le. Je voudrais pouvoir faire ce que je dis est impossible, et serais ravi d'être corrigé.
[~ # ~] edit [~ # ~] : Voici ma solution de contournement: implémenter .destroy()
pour mon pipeline bien qu'une série complexe de unpipe()
appelle. Et après toute cette complexité, cela ne fonctionne pas correctement dans tous les cas .
[~ # ~] éditer [~ # ~] : Node v8.0.0 ajouté un destroy()
api pour les flux lisibles .
À la version 4.*.*
l'insertion d'une valeur nulle dans le flux déclenchera un signal EOF
.
De la documentation de nodejs
Si une valeur autre que null est transmise, la méthode Push () ajoute un bloc de données à la file d'attente pour que les processeurs de flux ultérieurs l'utilisent. Si null est passé, il signale la fin du flux (EOF), après quoi aucune autre donnée ne peut être écrite.
Cela a fonctionné pour moi après avoir essayé de nombreuses autres options sur cette page.
Ce module destroy est destiné à assurer la destruction d’un flux de données, en traitant différentes API et bogues Node.js. En ce moment est l'un des meilleurs choix.
NB. À partir de Node 10, vous pouvez utiliser le .destroy
méthode sans autres dépendances.
C'est une vieille question, mais moi aussi je cherchais la réponse et j'ai trouvé la meilleure pour ma mise en œuvre. Les deux événements end
et close
sont émis, alors je pense que c'est la solution la plus propre.
Cela fera l'affaire dans le noeud 4.4. * (Version stable au moment de l'écriture):
var input = fs.createReadStream('lines.txt');
input.on('data', function(data) {
if (gotFirstLine) {
this.end(); // Simple isn't it?
console.log("Closed.");
}
});
Pour une explication très détaillée, voir: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm
Vous pouvez effacer et fermer le flux avec yourstream.resume()
, qui videra tout le contenu du flux et le fermera éventuellement.
De la document officiel :
readable.resume ():
Retour: ceci
Cette méthode fera en sorte que le flux lisible recommence à émettre des événements 'data'.
Cette méthode basculera le flux en mode fluide. Si vous ne souhaitez pas utiliser les données d'un flux, mais souhaitez accéder à son événement 'end', vous pouvez appeler stream.resume () pour ouvrir le flux de données.
var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
console.log('got to the end, but did not read anything');
});
Ce code va faire l'affaire ici:
function closeReadStream(stream) {
if (!stream) return;
if (stream.close) stream.close();
else if (stream.destroy) stream.destroy();
}
writeStream.end () est le moyen idéal de fermer un writeStream ...