如何从Node.Js中的string创buildstream?
我正在使用库, 雅-csv ,期待文件或stream作为input,但我有一个string。
如何将该string转换为Node中的stream?
正如@substack在#node中纠正了我的情况 ,Node v10中的新streamAPI使这一点变得更加简单:
var Readable = require('stream').Readable; var s = new Readable(); s._read = function noop() {}; // redundant? see update below s.push('your text here'); s.push(null);
…之后,你可以自由地pipe它 ,否则传递给你的目标消费者。
它不如一行的干净,但它确实避免了额外的依赖。
( 更新:在v0.10.26中,如果你没有设置_read
直接从REPL提示符下直接进行的调用将会崩溃, not implemented
一个not implemented
exception,它不会在函数或脚本内部崩溃,如果不一致,包括noop
。
不要使用Jo Liss的resumer答案。 它会在大多数情况下工作,但在我的情况下,它使我失去了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
这应该是一个完全兼容的可读stream。 有关如何正确使用stream的更多信息, 请参阅此处 。
老回答 :只需使用本地PassThroughstream:
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 })
请注意,“close”事件不会被发射(这不是stream接口所要求的)。
只需创build一个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');
编辑: 加思的答案可能会更好。
我的旧答案文本保存在下面。
要将string转换为stream,可以使用暂停的stream:
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()
有一个模块: https : //gist.github.com/kawanet/8aea35dc4a578f09757d
/** * @see https://www.npmjs.com/package/string-to-stream */ var str = require('string-to-stream') str('hi there').pipe(process.stdout) // => 'hi there'
在咖啡剧本:
class StringStream extends Readable constructor: (@str) -> super() _read: (size) -> @push @str @push null
用它:
new StringStream('text here').pipe(stream1).pipe(stream2)
我已经厌倦了每半年需要重新学习一次,所以我刚刚发布了一个npm模块来抽象出实现细节:
https://www.npmjs.com/package/streamify-string
这是模块的核心:
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
是可以传递给stream的典型选项,根据文档 。
根据Travis CI,它应该与大多数版本的节点兼容。
JavaScript是duck-typed,所以如果你只是复制一个可读的stream的API ,它会工作得很好。 事实上,你可能不能实现大部分的这些方法,或者把它们留作存根; 所有你需要实现的是图书馆使用的。 您也可以使用Node的预先构build的EventEmitter
类来处理事件,所以您不必自己实现addListener
等。
以下是您可以在CoffeeScript中实现的方法:
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'
那么你可以这样使用它:
stream = new StringStream someString doSomethingWith stream stream.send()