Je pirate un programme Node qui utilise smtp-protocol
pour capturer les e-mails SMTP et agir sur les données de messagerie. La bibliothèque fournit les données de messagerie sous forme de flux, et je ne sais pas comment les intégrer dans une chaîne.
Je l'écris actuellement sur stdout avec stream.pipe(process.stdout, { end: false })
, mais comme je l'ai dit, j'ai besoin des données de flux dans une chaîne à la place, que je peux utiliser une fois le flux terminé.
Comment collecter toutes les données d'un flux Node.js dans une chaîne?
javascript
node.js
stream
obrienmd
la source
la source
Réponses:
(Cette réponse date d'il y a des années, quand c'était la meilleure réponse. Il y a maintenant une meilleure réponse en dessous de celle-ci. Je n'ai pas suivi le node.js, et je ne peux pas supprimer cette réponse car elle est marquée "correct sur cette question ". Si vous envisagez de cliquer, que voulez-vous que je fasse?)
La clé est d'utiliser les événements
data
etend
d'un flux lisible . Écoutez ces événements:Lorsque vous recevez l'
data
événement, ajoutez le nouveau bloc de données à un tampon créé pour collecter les données.Lorsque vous recevez l'
end
événement, convertissez le tampon terminé en une chaîne, si nécessaire. Ensuite, faites ce que vous devez en faire.la source
Une autre façon serait de convertir le flux en une promesse (reportez-vous à l'exemple ci-dessous) et d'utiliser
then
(ouawait
) pour affecter la valeur résolue à une variable.la source
SyntaxError: await is only valid in async function
. Qu'est-ce que je fais mal?streamToString(stream).then(function(response){//Do whatever you want with response});
.toString("utf8")
la fin, pour éviter le problème d'un échec de décodage si un morceau est divisé au milieu d'un caractère multi-octets; (2) la gestion des erreurs réelles; (3) mettre le code dans une fonction, afin qu'il puisse être réutilisé et non copié; (4) en utilisant des promesses pour que la fonction puisse êtreawait
activée; (5) petit code qui ne traîne pas dans un million de dépendances, contrairement à certaines bibliothèques npm; (6) Syntaxe ES6 et meilleures pratiques modernes.Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
si le flux produisait desstring
morceaux au lieu deBuffer
. L'utilisationchunks.push(Buffer.from(chunk))
devrait fonctionner avec les deuxstring
et lesBuffer
morceaux.Aucun de ces éléments n'a fonctionné pour moi. J'avais besoin d'utiliser l'objet Buffer:
la source
J'espère que cela est plus utile que la réponse ci-dessus:
Notez que la concaténation de chaînes n'est pas le moyen le plus efficace de collecter les parties de chaîne, mais elle est utilisée pour plus de simplicité (et peut-être que votre code ne se soucie pas de l'efficacité).
En outre, ce code peut produire des échecs imprévisibles pour le texte non ASCII (il suppose que chaque caractère tient dans un octet), mais peut-être que vous ne vous en souciez pas non plus.
la source
join("")
le tableau à la fin.J'utilise généralement cette fonction simple pour transformer un flux en une chaîne:
Exemple d'utilisation:
la source
chunks.push(chunk.toString());
Et encore un autre pour les chaînes utilisant des promesses:
Usage:
supprimez le
.toString()
à utiliser avec des données binaires si nécessaire.mise à jour : @AndreiLED a correctement souligné que cela avait des problèmes avec les chaînes. Je n'ai pas pu obtenir un flux renvoyant des chaînes avec la version du nœud que j'ai, mais l' API note que c'est possible.
la source
Uncaught TypeError [ERR_INVALID_ARG_TYPE]: The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type string
si le flux produisait desstring
morceaux au lieu deBuffer
. L'utilisationchunks.push(Buffer.from(chunk))
devrait fonctionner avec les deuxstring
et lesBuffer
morceaux.À partir de la documentation de nodejs , vous devriez le faire - souvenez-vous toujours d'une chaîne sans savoir que l'encodage n'est qu'un tas d'octets:
la source
Les flux n'ont pas de
.toString()
fonction simple (que je comprends) ni quelque chose comme une.toStringAsync(cb)
fonction (que je ne comprends pas).J'ai donc créé ma propre fonction d'assistance:
la source
J'ai eu plus de chance en utilisant comme ça:
J'utilise node
v9.11.1
etreadstream
c'est la réponse d'unhttp.get
rappel.la source
La solution la plus propre peut être d'utiliser le package "string-stream", qui convertit un flux en chaîne avec une promesse.
la source
Un moyen simple avec la bibliothèque get-stream populaire (plus de 5 millions de téléchargements hebdomadaires) et légère :
https://www.npmjs.com/package/get-stream
la source
Et quelque chose comme un réducteur de flux?
Voici un exemple d'utilisation des classes ES6 comment en utiliser une.
la source
Cela a fonctionné pour moi et est basé sur la documentation Node v6.7.0 :
la source
setEncoding ('utf8');
Bravo Sebastian J ci-dessus.
J'ai eu le "problème de tampon" avec quelques lignes de code de test que j'avais, et j'ai ajouté les informations d'encodage et cela l'a résolu, voir ci-dessous.
Démontrez le problème
Logiciel
contribution
production
Démontrez la solution
Logiciel
contribution
production
la source
Toutes les réponses répertoriées semblent ouvrir le flux lisible en mode fluide, ce qui n'est pas la valeur par défaut dans NodeJS et peut avoir des limitations car il ne prend pas en charge la contre-pression que NodeJS fournit en mode de flux lisible en pause. Voici une implémentation utilisant Just Buffers, Native Stream et Native Stream Transforms et prise en charge du mode objet
la source
Que pensez-vous de ceci ?
la source
En utilisant le package très populaire
stream-buffers
que vous avez probablement déjà dans les dépendances de votre projet, c'est assez simple:la source
Dans mon cas, les en-têtes de réponse du type de contenu étaient Content-Type: text / plain . Donc, j'ai lu les données de Buffer comme:
la source