Ich verwende eine Bibliothek, ya-csv, die entweder eine Datei oder einen Stream als Eingabe erwartet, aber ich habe eine Zeichenfolge .
Wie konvertiere ich diese Zeichenfolge in einen Stream in Node?
11 Antworten
Ab Knoten 12.3 verfügt stream.Readable über eine from
-Methode, mit der Streams auf einfache Weise aus beliebigen iterierbaren Elementen (einschließlich Array-Literalen) erstellt werden können:
const { Readable } = require('stream')
const readable = Readable.from('input string')
readable.on("data", (chunk) => {
console.log(chunk) // will be called once with `"input string"`
})
Bearbeiten: Garth's Antwort ist wahrscheinlich besser.
Mein alter Antworttext bleibt unten erhalten.
Um eine Zeichenfolge in einen Stream zu konvertieren, können Sie einen angehaltenen bis Stream verwenden:
through().pause().queue('your string').end()
Beispiel:
var through = require('through')
// Create a paused stream and buffer some data into it:
var stream = through().pause().queue('your string').end()
// Pass stream around:
callback(null, stream)
// Now that a consumer has attached, remember to resume the stream:
stream.resume()
JavaScript ist vom Typ Ente. Wenn Sie also nur API eines lesbaren Streams kopieren, wird dies der Fall sein funktioniert gut. In der Tat können Sie wahrscheinlich die meisten dieser Methoden nicht implementieren oder sie einfach als Stubs belassen. Alles, was Sie implementieren müssen, ist das, was die Bibliothek verwendet. Sie können die vorgefertigte EventEmitter
-Klasse von Node auch verwenden, um Ereignisse zu behandeln Sie müssen also addListener
und dergleichen nicht selbst implementieren.
So können Sie es in CoffeeScript implementieren:
class StringStream extends require('events').EventEmitter
constructor: (@string) -> super()
readable: true
writable: false
setEncoding: -> throw 'not implemented'
pause: -> # nothing to do
resume: -> # nothing to do
destroy: -> # nothing to do
pipe: -> throw 'not implemented'
send: ->
@emit 'data', @string
@emit 'end'
Dann könnten Sie es so verwenden:
stream = new StringStream someString
doSomethingWith stream
stream.send()
Im Kaffeeskript:
class StringStream extends Readable
constructor: (@str) ->
super()
_read: (size) ->
@push @str
@push null
Benutze es:
new StringStream('text here').pipe(stream1).pipe(stream2)
Verwenden Sie nicht die Antwort von Jo Liss. Es wird in den meisten Fällen funktionieren, aber in meinem Fall hat es mir gute 4 oder 5 Stunden Fehlersuche verloren. Hierfür sind keine Module von Drittanbietern erforderlich.
NEUE ANTWORT :
var Readable = require('stream').Readable
var s = new Readable()
s.push('beep') // the string you want
s.push(null) // indicates end-of-file basically - the end of the stream
Dies sollte ein vollständig kompatibler lesbarer Stream sein. Weitere Informationen zur ordnungsgemäßen Verwendung von Streams finden Sie hier.
ALTE ANTWORT : Verwenden Sie einfach den nativen PassThrough-Stream:
var stream = require("stream")
var a = new stream.PassThrough()
a.write("your string")
a.end()
a.pipe(process.stdout) // piping will work as normal
/*stream.on('data', function(x) {
// using the 'data' event works too
console.log('data '+x)
})*/
/*setTimeout(function() {
// you can even pipe after the scheduler has had time to do other things
a.pipe(process.stdout)
},100)*/
a.on('end', function() {
console.log('ended') // the end event will be called properly
})
Beachten Sie, dass das Ereignis 'close' nicht ausgegeben wird (was von den Stream-Schnittstellen nicht benötigt wird).
Dafür gibt es ein Modul: https://www.npmjs.com/package/string- to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
Eine andere Lösung besteht darin, die Lesefunktion an den Konstruktor von Readable zu übergeben (siehe doc Stream-lesbare Optionen).
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
Sie können nach der Verwendung an Rohr zum Beispiel
Als @substack wurde ich in # node, die neue Streams-API in Node v10 macht dies einfacher:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
… Danach können Sie es Pipe frei oder anderweitig an Ihren beabsichtigten Verbraucher weitergeben.
Es ist nicht so sauber wie der Resumer Einzeiler, aber es vermeidet die zusätzliche Abhängigkeit.
( Update: In Version 0.10.26 bis Version 9.2.1 stürzt ein Aufruf von push
direkt von der REPL-Eingabeaufforderung mit einer not implemented
- Ausnahme ab, wenn Sie dies nicht festgelegt haben _read
. Es stürzt nicht innerhalb einer Funktion oder eines Skripts ab. Wenn Inkonsistenz Sie nervös macht, schließen Sie das noop
ein.)
Erstellen Sie einfach eine neue Instanz des Moduls stream
und passen Sie sie Ihren Anforderungen an:
var Stream = require('stream');
var stream = new Stream();
stream.pipe = function(dest) {
dest.write('your string');
return dest;
};
stream.pipe(process.stdout); // in this case the terminal, change to ya-csv
Oder
var Stream = require('stream');
var stream = new Stream();
stream.on('data', function(data) {
process.stdout.write(data); // change process.stdout to ya-csv
});
stream.emit('data', 'this is my string');
Hier ist eine ordentliche Lösung in TypeScript:
import { Readable } from 'stream'
class ReadableString extends Readable {
private sent = false
constructor(
private str: string
) {
super();
}
_read() {
if (!this.sent) {
this.push(Buffer.from(this.str));
this.sent = true
}
else {
this.push(null)
}
}
}
const stringStream = new ReadableString('string to be streamed...')
Ich hatte es satt, dies alle sechs Monate neu lernen zu müssen, und habe gerade ein npm-Modul veröffentlicht, um die Implementierungsdetails zu abstrahieren:
https://www.npmjs.com/package/streamify-string
Dies ist der Kern des Moduls:
const Readable = require('stream').Readable;
const util = require('util');
function Streamify(str, options) {
if (! (this instanceof Streamify)) {
return new Streamify(str, options);
}
Readable.call(this, options);
this.str = str;
}
util.inherits(Streamify, Readable);
Streamify.prototype._read = function (size) {
var chunk = this.str.slice(0, size);
if (chunk) {
this.str = this.str.slice(size);
this.push(chunk);
}
else {
this.push(null);
}
};
module.exports = Streamify;
str
ist das string
, das beim Aufruf an den Konstruktor übergeben werden muss und vom Stream als Daten ausgegeben wird. options
sind die typischen Optionen, die gemäß der Dokumentation .
Laut Travis CI sollte es mit den meisten Versionen von Node kompatibel sein.