Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 基本流问题:难以将字符串发送到标准输出_Node.js - Fatal编程技术网

Node.js 基本流问题:难以将字符串发送到标准输出

Node.js 基本流问题:难以将字符串发送到标准输出,node.js,Node.js,我刚刚开始学习node中的流。我在内存中有一个字符串,我想把它放在一个应用转换的流中,并通过管道将其传递到进程.stdout。以下是我的尝试: var through = require('through'); var stream = through(function write(data) { this.push(data.toUpperCase()); }); stream.push('asdf'); stream.pipe(process.stdout); stream.

我刚刚开始学习node中的流。我在内存中有一个字符串,我想把它放在一个应用转换的流中,并通过管道将其传递到
进程.stdout
。以下是我的尝试:

var through = require('through');

var stream = through(function write(data) {
    this.push(data.toUpperCase());
});

stream.push('asdf');

stream.pipe(process.stdout);

stream.end();
它不起作用。当我通过节点在cli上运行脚本时,不会向stdout发送任何内容,也不会抛出任何错误。我有几个问题:

  • 如果您在内存中有一个要放入流的值,那么最好的方法是什么
  • push
    queue
    之间有什么区别
  • 在调用
    pipe()
    之前或之后调用
    end()
    有关系吗
  • end()
    是否等同于
    push(null)

  • 谢谢

    基于流()的示例

    通过()


    看起来您没有正确使用流。。。如果使用write(…)而不是push(…),会发生什么情况?

    基于stream()

    通过()


    看起来您没有正确使用流。。。如果使用write(…)而不是push(…),会发生什么情况?

    只需使用香草流API即可

    var Transform = require("stream").Transform;
    
    // create a new Transform stream
    var stream = new Transform({
      decodeStrings: false,
      encoding: "ascii"
    });
    
    // implement the _transform method
    stream._transform = function _transform(str, enc, done) {
      this.push(str.toUpperCase() + "\n";
      done();
    };
    
    // connect to stdout
    stream.pipe(process.stdout);
    
    // write some stuff to the stream
    stream.write("hello!");
    stream.write("world!");
    
    // output
    // HELLO!
    // WORLD!
    

    或者您可以构建自己的流构造函数。这就是流API的实际使用方式

    var Transform = require("stream").Transform;
    
    function MyStream() {
      // call Transform constructor with `this` context
      // {decodeStrings: false} keeps data as `string` type instead of `Buffer`
      // {encoding: "ascii"} sets the encoding for our strings
      Transform.call(this, {decodeStrings: false, encoding: "ascii"});
    
      // our function to do "work"
      function _transform(str, encoding, done) {
        this.push(str.toUpperCase() + "\n");
        done();
      }
    
      // export our function
      this._transform = _transform;
    }
    
    // extend the Transform.prototype to your constructor
    MyStream.prototype = Object.create(Transform.prototype, {
      constructor: {
        value: MyStream
      }
    });
    
    现在像这样使用它

    // instantiate
    var a = new MyStream();
    
    // pipe to a destination
    a.pipe(process.stdout);
    
    // write data
    a.write("hello!");
    a.write("world!");
    
    输出

    HELLO!
    WORLD!
    
    HELLO!HELLO!HELLO!
    WORLD!WORLD!WORLD!
    

    关于
    .push
    vs
    .write
    的一些其他说明

    • .write(str)
      将数据添加到可写缓冲区。它应该被称为外部。如果您认为流类似于双工文件句柄,那么它就像
      fwrite
      ,只是缓冲的

    • .push(str)
      将数据添加到可读缓冲区。它只打算从我们的流中调用

    • .push(str)
      可以多次调用。观察如果我们将函数更改为

      function _transform(str, encoding, done) {
        this.push(str.toUpperCase());
        this.push(str.toUpperCase());
        this.push(str.toUpperCase() + "\n");
        done();
      }
      
      输出

      HELLO!
      WORLD!
      
      HELLO!HELLO!HELLO!
      WORLD!WORLD!WORLD!
      

    只需使用香草流API即可

    var Transform = require("stream").Transform;
    
    // create a new Transform stream
    var stream = new Transform({
      decodeStrings: false,
      encoding: "ascii"
    });
    
    // implement the _transform method
    stream._transform = function _transform(str, enc, done) {
      this.push(str.toUpperCase() + "\n";
      done();
    };
    
    // connect to stdout
    stream.pipe(process.stdout);
    
    // write some stuff to the stream
    stream.write("hello!");
    stream.write("world!");
    
    // output
    // HELLO!
    // WORLD!
    

    或者您可以构建自己的流构造函数。这就是流API的实际使用方式

    var Transform = require("stream").Transform;
    
    function MyStream() {
      // call Transform constructor with `this` context
      // {decodeStrings: false} keeps data as `string` type instead of `Buffer`
      // {encoding: "ascii"} sets the encoding for our strings
      Transform.call(this, {decodeStrings: false, encoding: "ascii"});
    
      // our function to do "work"
      function _transform(str, encoding, done) {
        this.push(str.toUpperCase() + "\n");
        done();
      }
    
      // export our function
      this._transform = _transform;
    }
    
    // extend the Transform.prototype to your constructor
    MyStream.prototype = Object.create(Transform.prototype, {
      constructor: {
        value: MyStream
      }
    });
    
    现在像这样使用它

    // instantiate
    var a = new MyStream();
    
    // pipe to a destination
    a.pipe(process.stdout);
    
    // write data
    a.write("hello!");
    a.write("world!");
    
    输出

    HELLO!
    WORLD!
    
    HELLO!HELLO!HELLO!
    WORLD!WORLD!WORLD!
    

    关于
    .push
    vs
    .write
    的一些其他说明

    • .write(str)
      将数据添加到可写缓冲区。它应该被称为外部。如果您认为流类似于双工文件句柄,那么它就像
      fwrite
      ,只是缓冲的

    • .push(str)
      将数据添加到可读缓冲区。它只打算从我们的流中调用

    • .push(str)
      可以多次调用。观察如果我们将函数更改为

      function _transform(str, encoding, done) {
        this.push(str.toUpperCase());
        this.push(str.toUpperCase());
        this.push(str.toUpperCase() + "\n");
        done();
      }
      
      输出

      HELLO!
      WORLD!
      
      HELLO!HELLO!HELLO!
      WORLD!WORLD!WORLD!
      

    首先,您要使用
    write()
    ,而不是
    push()
    write()
    将数据放入流,
    push()
    将数据推出流;只有在实现自己的
    可读流
    双工流
    转换流时,才能使用
    push()

    其次,在设置了
    管道()
    (或添加了一些事件侦听器)之后,您只想
    将数据写入流。如果您在没有连接到另一端的情况下写入流,那么您写入的数据将丢失。正如@naomik所指出的,这在一般情况下是不正确的,因为
    writeable
    流将缓冲
    write()
    s。在您的示例中,您确实需要在
    pipe()之后
    write()
    。否则,进程将在将任何内容写入
    STDOUT
    之前结束。这可能是由于
    模块是如何实现的,但我不确定这一点

    因此,考虑到这一点,您可以对示例进行一些简单的更改以使其正常工作:

    var through = require('through');
    
    var stream = through(function write(data) {
        this.push(data.toUpperCase());
    });
    
    stream.pipe(process.stdout);
    
    stream.write('asdf');
    stream.end();
    
    现在,请回答您的问题:

  • 将数据从内存中获取到可写流的最简单方法是简单地
    write()
    它,就像我们在您的示例中使用
    stream.wrtie('asdf')
    所做的那样
  • 据我所知,流没有
    queue()
    函数,你是说
    write()
    ?正如我上面所说,
    write()
    用于将数据放入流,
    push()
    用于将数据从流中推出。仅在您自己的流实现中调用
    push()
  • 仅在将所有数据写入流后调用
    end()
    end()
    基本上说:“好的,我现在完成了。请完成您正在做的事情并关闭流。”
  • push(null)
    相当于
    end()
    。也就是说,不要调用
    push(null)
    ,除非您在自己的流实现中这样做(如上所述)。调用
    end()
    几乎总是更合适的

  • 首先,您希望使用
    write()
    ,而不是
    push()
    write()
    将数据放入流,
    push()
    将数据推出流;只有在实现自己的
    可读流
    双工流
    转换流时,才能使用
    push()

    其次,在设置了
    管道()
    (或添加了一些事件侦听器)之后,您只想
    将数据写入流。如果您在没有连接到另一端的情况下写入流,那么您写入的数据将丢失。正如@naomik所指出的,这在一般情况下是不正确的,因为
    writeable
    流将缓冲
    write()
    s。在您的示例中,您确实需要在
    pipe()之后
    write()
    。否则,进程将在将任何内容写入
    STDOUT
    之前结束。这可能是由于
    模块是如何实现的,但我不确定这一点

    因此,考虑到这一点,您可以对示例进行一些简单的更改以使其正常工作:

    var through = require('through');
    
    var stream = through(function write(data) {
        this.push(data.toUpperCase());
    });
    
    stream.pipe(process.stdout);
    
    stream.write('asdf');
    stream.end();
    
    现在,请回答您的问题:

  • 将数据从内存中获取到可写内存的最简单方法是