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'empêcherait pas le processus de lecture ...
fs
module.close
n'existe pas enStream.Readable
.stream.destroy()
readable.push(null) && readable.destroy();
Réponses:
Invoquez
input.close()
. Ce n'est pas dans la documentation, maishttps://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
fait clairement le travail :) Il fait quelque chose de similaire au vôtre
isEnded
.EDIT 2015-Apr-19 Basé sur les commentaires ci-dessous, et pour clarifier et mettre à jour:
lib/fs.js
cela fonctionne toujours> 1,5 ans plus tard.destroy()
est préférable.fs
ReadStreams
les, pas sur un génériqueReadable
Quant à une solution générique: il ne semble pas y en avoir une, du moins d'après ma compréhension de la documentation et d'un rapide coup d'œil
_stream_readable.js
.Ma proposition serait de mettre votre flux lisible en mode suspendu , empêchant au moins un traitement ultérieur dans votre source de données en amont. N'oubliez pas de
unpipe()
supprimer tous lesdata
écouteurs d'événements pour qu'ilspause()
se mettent en pause, comme indiqué dans la documentationla source
destroy
place. Du moins, c'est ce qu'on appelle si vous définissez autoClose sur true. En regardant le code source (aujourd'hui) les différences sont minimes (destroy
appelsclose
) mais cela pourrait changer à l'avenirclose()
d'objet lisible, n'y a-t-il jamais de solution? Mon échange de données est toujours incomplet ...Edit: Bonne nouvelle! À partir de Node.js 8.0.0
readable.destroy
est officiellement disponible: https://nodejs.org/api/stream.html#stream_readable_destroy_errorReadStream.destroy
Vous pouvez appeler la fonction ReadStream.destroy à tout moment.
La fonction publique
ReadStream.destroy
n'est pas documentée (Node.js v0.12.2) mais vous pouvez consulter le code source sur GitHub ( validation du 5 octobre 2012 ).La
destroy
fonction marque en interne l'ReadStream
instance comme détruite et appelle laclose
fonction pour libérer le fichier.Vous pouvez écouter l' événement de fermeture pour savoir exactement quand le fichier est fermé. L' événement de fin ne se déclenchera que si les données sont complètement consommées.
Notez que les
destroy
(et lesclose
) fonctions sont spécifiques à fs.ReadStream . Il n'y a pas de partie de l ' "interface" stream.readable générique .la source
error
s'il n'est jamais lu. En dehors de cela, la seule autre fuite dont je m'inquiéterais concerne les gestionnaires d'événements - encore une fois, je ne suis pas sûr à 100% à ce sujet, mais nous pourrions être d'accord car l'Évangile d'Isaacs de 2010 dit que les gestionnaires sont élagué lorsque les émetteurs sont gc'd: groups.google.com/d/msg/nodejs/pXbJVo0NtaY/BxUmF_jp9LkJon('data')
ne se déclenchera qu'une seule fois, donc il n'y en aura pas.close()
, rappelez-le simplement à quelqu'un d'autre.Aujourd'hui, dans le nœud 10
readableStream.destroy()
est le moyen officiel de fermer un flux lisible
voir https://nodejs.org/api/stream.html#stream_readable_destroy_error
la source
Vous ne pouvez pas. Il n'existe aucun moyen documenté de fermer / arrêter / abandonner / détruire un flux lisible générique à partir de Node 5.3.0. Il s'agit d'une limitation de l'architecture de flux Node.
Comme d'autres réponses l'ont expliqué ici, il existe des hacks non documentés 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 Readable.
Si quelqu'un peut me prouver le contraire, faites-le. J'aimerais 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 via une série complexe d'unpipe()
appels. Et après toute cette complexité, cela ne fonctionne pas correctement dans tous les cas .EDIT : Node v8.0.0 a ajouté une
destroy()
API pour les flux lisibles .la source
stream.pipeline
, qui prétend gérer "les erreurs de transfert et nettoyer correctement et fournir un rappel lorsque le pipeline est terminé." Est ce que ça aide?À la version,
4.*.*
pousser une valeur nulle dans le flux déclenchera unEOF
signal.À partir de la documentation nodejs
Cela a fonctionné pour moi après avoir essayé de nombreuses autres options sur cette page.
la source
Ce module de destruction est destiné à garantir qu'un flux est détruit, en traitant différentes API et bogues Node.js. En ce moment, c'est l'un des meilleurs choix.
NB. Depuis Node 10, vous pouvez utiliser la
.destroy
méthode sans autres dépendances.la source
Vous pouvez effacer et fermer le flux avec
yourstream.resume()
, qui videra tout sur le flux et le fermera éventuellement.À partir des documents officiels :
la source
'data'
écouteur d'événements, mais nous l'avons fait vérifier un booléenif (!ignoring) { ... }
afin qu'il ne traite pas les données lorsque nous vidons le flux.ignoring = true; readable.resume();
'end'
à un moment donné. Tous les streams ne le feront pas! (Par exemple, un flux qui envoie la date toutes les secondes, pour toujours.)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
end
etclose
événements sont émis, donc je pense que c'est la solution la plus propre.Cela fera l'affaire dans le nœud 4.4. * (Version stable au moment de l'écriture):
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
la source
Ce code ici fera très bien l'affaire:
writeStream.end () est le moyen idéal pour fermer un writeStream ...
la source
.end