我正在使用一个库,ya-csv,它需要文件或流作为输入,但是我有一个字符串。
在Node中,如何将该字符串转换为流?
正如@substack在#node中纠正我的一样,Node v10 中的新 流 API使得这更容易:
const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);
之后,您可以自由地传输它或以其他方式将其传递给您计划的消费者。
这不如resumer一句话的处理干净,但它确实避免了额外的依赖。
(更新:目前在v0.10.26到v9.2.1中,如果您没有设置_read
,直接从REPL提示符调用push
将导致not implemented
异常。它不会在函数或脚本内崩溃。如果不一致让您紧张,包括noop
。)
不要使用Jo Liss的回答。在大多数情况下,它可能有效,但在我的情况下,它让我花了整整4到5个小时来查找错误。没有必要使用第三方模块来完成这个任务。
新的回答:
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
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
})
从node 10.17版本开始,stream.Readable有一个from
方法,可以轻松地从任何可迭代对象(包括数组字面量)创建流:
const { Readable } = require("stream")
const readable = Readable.from(["input string"])
readable.on("data", (chunk) => {
console.log(chunk) // will be called once with `"input string"`
})
Readable.from("input string")
将有效,但会每个字符发出一个事件。Readable.from(["input string"])
将为数组中的每个项(在此情况下为一个项)发出一个事件。https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options
只需创建一个 stream
模块的新实例并根据您的需要进行自定义:
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
或者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');
pipe()
应该至少返回目标流。 - greim编辑: Garth的回答 可能更好。
我的旧回答内容保留如下。
要将字符串转换为流,您可以使用一个已暂停的through 流:
through().pause().queue('your string').end()
例子:
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()
resumer
效果非常好。谢谢! - mpen有一个模块可以实现这个功能:https://www.npmjs.com/package/string-to-stream
var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there'
var s = new Readable({read(size) {
this.push("your string here")
this.push(null)
}});
在 CoffeeScript 中:
class StringStream extends Readable
constructor: (@str) ->
super()
_read: (size) ->
@push @str
@push null
使用它:
new StringStream('text here').pipe(stream1).pipe(stream2)
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
是在调用构造函数时必须传递的string
,并将作为数据由流输出。 options
是可以传递给流的典型选项,根据文档。
根据Travis CI的说法,它应该与大多数Node版本兼容。
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...')
_read
方法来从底层资源获取数据。【注:此为 Node.js 官方文档中某部分内容的翻译】 - Felix Rabenull
推入流的缓冲区? - dopatramannull
表示流已经读取完所有数据并关闭了流。 - chrishiestandreadable.push()
方法仅适用于Readable的实现者,并且只能从readable._read()
方法内部调用。” - Axel Rauschmayer