Como fechar um fluxo legível em 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.");
}
});
Isso seria melhor do que:
input.on('data', function(data) {
if (isEnded) { return; }
if (gotFirstLine) {
isEnded = true;
console.log("Closed.");
}
});
Mas isso não iria parar o processo de leitura ...
fs
módulo.close
não existe emStream.Readable
.stream.destroy()
readable.push(null) && readable.destroy();
Respostas:
Invoque
input.close()
. Não está nos documentos, mashttps://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620
claramente faz o trabalho :) Na verdade, faz algo semelhante ao seu
isEnded
.EDITAR 2015-abr-19 Com base nos comentários abaixo, e para esclarecer e atualizar:
lib/fs.js
ele ainda funcione> 1,5 anos depois.destroy()
ser preferível.fs
ReadStreams
's, não em um genéricoReadable
Quanto a uma solução genérica: não parece que exista, pelo menos pelo meu entendimento da documentação e por uma rápida olhada
_stream_readable.js
.Minha proposta seria colocar seu fluxo legível em modo pausado , pelo menos evitando processamento adicional em sua fonte de dados upstream. Não se esqueça de
unpipe()
remover todos osdata
ouvintes de eventos para quepause()
realmente sejam pausados, conforme mencionado nos documentosfonte
destroy
vez disso. Pelo menos é o que é chamado se você definir autoClose como true. Olhando o código fonte (hoje) as diferenças são mínimas (destroy
ligaçõesclose
), mas isso pode mudar no futuroclose()
objeto Legível, há uma solução nunca? Minha troca de dados está sempre incompleta ...Edit: Boas notícias! A partir do Node.js 8.0.0
readable.destroy
está oficialmente disponível: https://nodejs.org/api/stream.html#stream_readable_destroy_errorReadStream.destroy
Você pode chamar a função ReadStream.destroy a qualquer momento.
A função pública
ReadStream.destroy
não está documentada (Node.js v0.12.2), mas você pode dar uma olhada no código-fonte no GitHub ( commit de 5 de outubro de 2012 ).A
destroy
função marca internamente aReadStream
instância como destruída e chama aclose
função para liberar o arquivo.Você pode ouvir o evento close para saber exatamente quando o arquivo é fechado. O evento de término não será disparado a menos que os dados sejam totalmente consumidos.
Observe que as funções
destroy
(eclose
) são específicas para fs.ReadStream . Não faz parte da "interface" stream.readable genérica .fonte
error
se nunca for lido. Além disso, o único outro vazamento com o qual eu me preocuparia são os manipuladores de eventos - mais uma vez, não tenho 100% de certeza sobre isso, mas podemos estar bem, porque 2010 o evangelho de Isaacs diz que os manipuladores são podado quando os emissores são obtidos: groups.google.com/d/msg/nodejs/pXbJVo0NtaY/BxUmF_jp9LkJon('data')
será disparado apenas uma vez, então não haverá nenhum.close()
, basta lembrar outra pessoa.Hoje, no Nó 10
readableStream.destroy()
é a forma oficial de fechar um fluxo legível
consulte https://nodejs.org/api/stream.html#stream_readable_destroy_error
fonte
Você não pode. Não há maneira documentada de fechar / desligar / abortar / destruir um fluxo legível genérico a partir do Nó 5.3.0. Esta é uma limitação da arquitetura de fluxo do Node.
Como outras respostas aqui explicaram, existem hacks não documentados para implementações específicas de Readable fornecidas pelo Node, como fs.ReadStream . No entanto, essas não são soluções genéricas para qualquer legível.
Se alguém puder provar que estou errado aqui, por favor, faça. Eu gostaria de poder fazer o que estou dizendo que é impossível, e ficaria muito feliz em ser corrigido.
EDIT : Aqui estava minha solução alternativa: implementar
.destroy()
para meu pipeline por meio de uma série complexa deunpipe()
chamadas. E depois de toda essa complexidade, ele não funciona corretamente em todos os casos .EDIT : Node v8.0.0 adicionado um
destroy()
api para streams legíveis .fonte
stream.pipeline
, que afirma lidar com “erros de encaminhamento e limpeza adequada e fornecer um retorno de chamada quando o pipeline estiver concluído”. Isso ajuda?Na versão,
4.*.*
empurrar um valor nulo para o fluxo irá disparar umEOF
sinal.Dos documentos do nodejs
Isso funcionou para mim depois de tentar várias outras opções nesta página.
fonte
Este módulo destroy tem como objetivo garantir que um stream seja destruído, tratando de diferentes APIs e bugs do Node.js. Agora é uma das melhores escolhas.
NB. No Nó 10, você pode usar o
.destroy
método sem dependências adicionais.fonte
Você pode limpar e fechar o fluxo com
yourstream.resume()
, o que irá despejar tudo no fluxo e, eventualmente, fechá-lo.Dos documentos oficiais :
fonte
'data'
ouvinte de evento, mas fizemos com que ele marcasse um booleanoif (!ignoring) { ... }
para que ele não processasse dados quando estivermos drenando o fluxo.ignoring = true; readable.resume();
'end'
em algum ponto. Nem todos os streams farão isso! (Por exemplo, um stream que envia a data a cada segundo, para sempre.)É uma pergunta antiga, mas eu também estava procurando a resposta e encontrei a melhor para a minha implementação. Ambos os eventos
end
eclose
são emitidos, então acho que esta é a solução mais limpa.Isso resolverá o problema no nó 4.4. * (Versão estável no momento da escrita):
Para uma explicação muito detalhada, consulte: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm
fonte
Este código aqui vai fazer o truque muito bem:
writeStream.end () é a melhor maneira de fechar um writeStream ...
fonte
.end