Estou hackeando um programa Node que usa smtp-protocol
para capturar emails SMTP e agir sobre os dados de email. A biblioteca fornece os dados de correio como um fluxo, e não sei como colocá-los em uma string.
No momento, estou escrevendo para stdout com stream.pipe(process.stdout, { end: false })
, mas, como disse, preciso dos dados do fluxo em uma string, que posso usar assim que o fluxo terminar.
Como faço para coletar todos os dados de um fluxo Node.js em uma string?
javascript
node.js
stream
Obrienmd
fonte
fonte
Respostas:
(Esta resposta é de anos atrás, quando era a melhor resposta. Agora há uma resposta melhor abaixo. Eu não acompanhei o node.js e não posso excluir esta resposta porque está marcada como "correto nesta pergunta ". Se você está pensando em clicar, o que você quer que eu faça?)
A chave é usar os eventos
data
eend
de um fluxo legível . Ouça estes eventos:Ao receber o
data
evento, adicione o novo bloco de dados a um Buffer criado para coletar os dados.Ao receber o
end
evento, converta o Buffer preenchido em uma string, se necessário. Em seguida, faça o que você precisa fazer com ele.fonte
Outra forma seria converter o fluxo em uma promessa (consulte o exemplo abaixo) e usar
then
(ouawait
) para atribuir o valor resolvido a uma variável.fonte
SyntaxError: await is only valid in async function
. O que estou fazendo de errado?streamToString(stream).then(function(response){//Do whatever you want with response});
.toString("utf8")
no final, para evitar o problema de uma falha de decodificação se um chunk for dividido no meio de um caractere multibyte; (2) tratamento de erros real; (3) colocar o código em uma função, para que possa ser reutilizado, não copiado e colado; (4) usando Promises para que a função possa serawait
ativada; (5) pequeno código que não arrasta um milhão de dependências, ao contrário de certas bibliotecas npm; (6) Sintaxe ES6 e melhores práticas modernas.Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
se o fluxo produzirstring
pedaços em vez deBuffer
. O usochunks.push(Buffer.from(chunk))
deve funcionar com os blocosstring
eBuffer
.Nenhuma das opções acima funcionou para mim. Eu precisava usar o objeto Buffer:
fonte
Espero que seja mais útil do que a resposta acima:
Observe que a concatenação de string não é a maneira mais eficiente de coletar as partes da string, mas é usada para simplificar (e talvez seu código não se importe com a eficiência).
Além disso, esse código pode produzir falhas imprevisíveis para texto não ASCII (ele assume que cada caractere cabe em um byte), mas talvez você também não se importe com isso.
fonte
join("")
o array no final.Normalmente, estou usando esta função simples para transformar um stream em uma string:
Exemplo de uso:
fonte
chunks.push(chunk.toString());
E ainda outro para strings usando promessas:
Uso:
remova o
.toString()
para usar com dados binários, se necessário.update : @AndreiLED apontou corretamente que há problemas com strings. Não consegui obter um fluxo que retornasse strings com a versão do nó que possuo, mas a API observa que isso é possível.
fonte
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
se o fluxo produzirstring
pedaços em vez deBuffer
. O usochunks.push(Buffer.from(chunk))
deve funcionar com os blocosstring
eBuffer
.A partir da documentação do nodejs , você deve fazer isso - lembre-se sempre de uma string sem saber que a codificação é apenas um monte de bytes:
fonte
Streams não tem uma
.toString()
função simples (que eu entendo) nem algo como uma.toStringAsync(cb)
função (que eu não entendo).Então, criei minha própria função auxiliar:
fonte
Tive mais sorte usando assim:
Eu uso o nó
v9.11.1
ereadstream
é a resposta de umhttp.get
retorno de chamada.fonte
A solução mais limpa pode ser usar o pacote "string-stream", que converte um fluxo em uma string com uma promessa.
fonte
Maneira fácil com a biblioteca get-stream popular (mais de 5 milhões de downloads semanais) e leve :
https://www.npmjs.com/package/get-stream
fonte
Que tal algo como um redutor de fluxo?
Aqui está um exemplo usando classes ES6 como usar um.
fonte
Isso funcionou para mim e é baseado nos documentos do Node v6.7.0 :
fonte
setEncoding ('utf8');
Muito bem, Sebastian J acima.
Eu tive o "problema de buffer" com algumas linhas de código de teste que eu tinha, e adicionei as informações de codificação e isso resolveu, veja abaixo.
Demonstre o problema
Programas
entrada
resultado
Demonstre a solução
Programas
entrada
resultado
fonte
Todas as respostas listadas parecem abrir o fluxo legível no modo de fluxo, que não é o padrão no NodeJS e pode ter limitações, pois não tem suporte de contrapressão que o NodeJS fornece no modo de fluxo legível pausado. Aqui está uma implementação usando Just Buffers, Native Stream e Native Stream Transforms e suporte para o modo de objeto
fonte
O que você pensa sobre isso ?
fonte
Usando o pacote bastante popular
stream-buffers
que você provavelmente já tem nas dependências do seu projeto, isso é bastante simples:fonte
No meu caso, os cabeçalhos de resposta do tipo de conteúdo eram Content-Type: text / plain . Então, eu li os dados do Buffer como:
fonte