如何从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 implementedexception,它不会在函数或脚本内部崩溃,如果不一致,包括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()