javascript - Hur läser jag innehållet i en Node.js-ström till en strängvariabel?


Hur samlar jag all data från en Node.js-ström till en sträng?

Svar #1

Ett annat sätt skulle vara att konvertera strömmen till ett löfte (se exemplet nedan) och använda then (eller await) för att tilldela det lösta värdet till en variabel.

function streamToString (stream) {
  const chunks = [];
  return new Promise((resolve, reject) => {
    stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
    stream.on('error', (err) => reject(err));
    stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
  })
}

const result = await streamToString(stream)

Svar #2

Vad tycker du om detta?

async function streamToString(stream) {
    // lets have a ReadableStream as a stream variable
    const chunks = [];

    for await (const chunk of stream) {
        chunks.push(Buffer.from(chunk));
    }

    return Buffer.concat(chunks).toString("utf-8");
}

Svar #3

Inget av ovanstående fungerade för mig. Jag behövde använda Buffer-objektet:

  const chunks = [];

  readStream.on("data", function (chunk) {
    chunks.push(chunk);
  });

  // Send the buffer or you can put it into a var
  readStream.on("end", function () {
    res.send(Buffer.concat(chunks));
  });

Svar #4

Hoppas att detta är mer användbart än svaret ovan:

var string = '';
stream.on('data',function(data){
  string += data.toString();
  console.log('stream data ' + part);
});

stream.on('end',function(){
  console.log('final output ' + string);
});

Observera att strängsammanfogning inte är det mest effektiva sättet att samla strängdelarna, men det används för enkelhetens skull (och kanske bryr sig inte din kod om effektivitet).

Dessutom kan denna kod orsaka oförutsägbara fel för icke-ASCII-text (den antar att varje tecken får plats i en byte), men kanske bryr du dig inte om det heller.

Svar #5

(Detta svar är från för flera år sedan, när det var det bästa svaret. Det finns nu ett bättre svar nedan. Jag har inte hållit mig uppdaterad med node.js, och jag kan inte ta bort detta svar eftersom det är markerat som "korrekt på denna fråga". Om du tänker nedrösta, vad vill du att jag ska göra?)

Nyckeln är att använda data- och end-händelserna i en läsbar ström. Lyssna på dessa händelser:

stream.on('data', (chunk) => { ... });
stream.on('end', () => { ... });

När du tar emot data-händelsen, lägg till den nya databitens chunk till en Buffer skapad för att samla datan.

När du tar emot end-händelsen, konvertera den färdiga Buffern till en sträng, om det behövs. Gör sedan vad du behöver göra med den.

Svar #6

Det är enklast att använda Node.js inbyggda streamConsumers.text:

import { text } from 'node:stream/consumers';
import { Readable } from 'node:stream';

const readable = Readable.from('Hello world from consumers!');
const string = await text(readable);

Svar #7

Jag använder vanligtvis denna enkla funktion för att omvandla en ström till en sträng:

function streamToString(stream, cb) {
  const chunks = [];
  stream.on('data', (chunk) => {
    chunks.push(chunk.toString());
  });
  stream.on('end', () => {
    cb(chunks.join(''));
  });
}

Exempel på användning:

let stream = fs.createReadStream('./myFile.foo');
streamToString(stream, (data) => {
  console.log(data);  // data is now my string variable
});

Svar #8

Och ytterligare en för strängar som använder löften:

function getStream(stream) {
  return new Promise(resolve => {
    const chunks = [];

    # Buffer.from is required if chunk is a String, see comments
    stream.on("data", chunk => chunks.push(Buffer.from(chunk)));
    stream.on("end", () => resolve(Buffer.concat(chunks).toString()));
  });
}

Användning :

const stream = fs.createReadStream(__filename);
getStream(stream).then(r=>console.log(r));

ta bort .toString() för att använda med binär Data om det behövs.

uppdatering: @AndreiLED påpekade korrekt att detta har problem med strängar. Jag kunde inte få en stream som returnerar strängar med den version av node jag har, men API:et noterar att detta är möjligt.

Relaterade artiklar