如何将字符串转换为可读流?

Posted

技术标签:

【中文标题】如何将字符串转换为可读流?【英文标题】:How do I turn a String into a Readable Stream? 【发布时间】:2016-06-01 16:59:03 【问题描述】:

我正在尝试将一个字符串流式传输到另一个流:

streamer = new stream.Transform objectMode: true
stringer = (string) ->
    streamer._transform = (chunk, encoding, done) ->
        @push string.split('').shift()
        done()

    return streamer

streamer.on 'readable', ->
    console.log 'readable'

stringer('hello').pipe process.stdout

但是控制台中没有任何记录。我做错了什么?

【问题讨论】:

重复? ***.com/questions/12755997/… string-stream的源码可以作为参考.. 注意:本题的代码是 CoffeeScript,不是 javascript @Markasoftware 在该示例中运行代码时出现此错误:_stream_readable.js:480 dest.on('unpipe', onunpipe); ^ TypeError: Cannot read property 'on' of undefined 这个问题确实需要关闭。它已经在我发布的链接上有答案,还有其他资源也显示了如何在其他网站上做同样的事情。 【参考方案1】:

此代码似乎有效。我不太熟悉您在问题中使用的 ES6 和 ES7 中的所有新 JavaScript 语法,所以我只是从头开始重写:

const util=require('util');
const stream=require('stream');

var StringStream=function(strArg)
    stream.Readable.call(this);
    this.str=strArg.split('');


util.inherits(StringStream,stream.Readable);

StringStream.prototype._read=function(numRead)
    this.push(this.str.splice(0,numRead).join(''));


var thisIsAStringStream=new StringStream('this-is-test-text-1234567890');
thisIsAStringStream.pipe(process.stdout);

在我的系统上它输出this-is-test-text-1234567890,所以它工作正常。这与documentation 中推荐的方式完全相同 ,通过使用util.inherit创建一个扩展stream.Readable类的类,通过执行stream.Readable.call('this')在新类的构造函数内部调用stream.Readable的构造函数,并实现_read方法以从字符串使用this.push

如果不清楚,您可以使用以下方式创建流:

var helloWorldStream=new StringStream('HelloWorld');

然后您可以像使用任何可读流一样使用该流。

【讨论】:

我发现像这样使用继承的例子,它的解决方案太混乱了。是否有使用流的功能方法?类似于require('stream')(string).push('hello').pipe(process.stdout)? 这实际上是创建自定义可读流的官方方法。我可能会在今天晚些时候调查一些事情,但是是的。【参考方案2】:

如果您的最终目标是将字符串转换为可读流,只需使用模块into-stream。

var intoStream = require('into-stream')
intoStream('my-str').pipe(process.stdout)

另一方面,如果您想知道自己实际执行此操作的方法,则该模块的源代码有点迟钝,因此我将创建一个示例:

(您实际上不需要代码中的转换流,只需一个可写流)

var chars = 'my-str'.split('')
  , Stream = require('stream').Readable

new Stream( read: read ).pipe(process.stdout)

function read(n) 
  this.push(chars.shift())

注意。这仅适用于 Node 版本 >= 4。以前的版本没有 Stream 构造函数中的便捷方法。对于较旧的节点(0.10.x、0.12.x 等),以下稍长的示例将起作用……

var chars = 'my-str'.split('')
  , Stream = require('stream').Readable
  , s = new Stream()

s._read = function (n) 
  this.push(chars.shift())


s.pipe(process.stdout)

【讨论】:

【参考方案3】:

正如您所说,您需要的是可读流而不是转换流。此外,您还有一个错误,因为string.split('') 总是返回相同的数组,然后.shift() 总是返回相同的字母。重写后的代码如下:

'use strict'

Readable = require('stream').Readable

stringer = (string) ->
  array = string.split('')
  new Readable
    read: (size) ->
      @push array.shift()
      return

readable = stringer('hello')

readable.on 'readable', ->
  console.log 'readable'
  return

readable.pipe process.stdout

【讨论】:

【参考方案4】:

在 Node 10.x 中,添加了 Readable.from 便捷方法,这使得它更容易实现。

const Readable = require('stream').Readable;

Readable.from('hello').pipe(process.stdout);

【讨论】:

以上是关于如何将字符串转换为可读流?的主要内容,如果未能解决你的问题,请参考以下文章

如何将八位字节字符串转换为可读字符串[重复]

将 unsigned char* 转换为可读字符串 & 这个函数在做啥

如何在 Swift 中将多字符数字格式转换为可读的字符串?

改进将字符串转换为可读 url

将 unicode 转换为可读字符串

转义命令/ ByteArray转换为可读文本C#