节点流 - 在可读流中侦听unpipe

时间:2017-03-31 22:56:54

标签: node.js fs node-streams

因此,我创建了一个首先连接到SFTP并开始从文件读取的读取流。在任何时候,我的代码都可以取消管理该读取流并执行其他操作。例如,我可能会使用它来获取CSV的前几行并停止阅读。

问题是,我不知道如何在readStream构造函数中监听unpipe事件,以便我可以正确关闭SFTP连接。我在写流中使用flush方法,是否有类似读取流的方法?

这是我的readStream构造函数的简化部分:

const Client = require('ssh2').Client,
      nom = require('noms');

function getStream (get) {
    const self = this;
    const conn = new Client();

    let client,
        fileData,
        buffer,
        totalBytes = 0,
        bytesRead = 0;

    let read = function(size,next) {
        const read = this;
        // Read each chunk of the file
        client.read(fileData, buffer, bytesRead, size, bytesRead,
            function (err, byteCount, buff, pos) {
                bytesRead += byteCount;
                read.push(buff);
                next();
            }
        );
    };

    let before = function(start) {
        // setup the connection BEFORE we start _read
        conn.on('ready', function(){
            conn.sftp(function(err,sftp) {
                sftp.open(get, 'r', function(err, fd){
                    sftp.fstat(fd, function(err, stats) {
                        client = sftp;
                        fileData = fd;
                        totalBytes = stats.size;
                        buffer = new Buffer(totalBytes);

                        start();
                    });
                });
            });
        }).connect(credentials);
    };

    return nom(read,before);
}

稍后我可以致电myStream.pipe(writeStream)然后myStream.unpipe()。但由于我无法监听unpipe事件,因此读取停止,但SFTP连接保持打开状态并最终超时。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

因此,经过更多研究,我了解到当您调用unpipe时,ReadStreams未通过readStream.unpipe(writeStream)事件。该事件只传递给writeStream。为了监听unpipe,你需要在readStream上显式地发出一个事件,如下所示:

readStream.emit('unpipe');

您可以在流构造函数内部或外部的任何位置侦听此事件,这非常方便。所以,这会使上面的代码看起来像这样:

function getStream (get) {
    /**
     * ... stuff
     * ... read()
     * ... before()
     * ... etc
     */

    let readStream = nom(read,before);

    readStream.on('unpipe', function(){
        console.log('called unpipe on read stream');
    });

    return readStream;
}

故事的道德,流已经有Event Emitter class methods,因此您可以开箱即可发出和收听自定义事件。