【问题标题】:How to redirect a stream to other stream depending on data in first chunk?如何根据第一个块中的数据将流重定向到其他流?
【发布时间】:2015-10-20 08:23:40
【问题描述】:

我正在使用 Busboy 处理多部分形式的文件。简化版流程如下:

file.pipe(filePeeker).pipe(gzip).pipe(encrypt).pipe(uploadToS3)

filePeeker 是一个直通流(使用 trough2 构建)。此双工流执行以下操作:

  • 通过查看第一个块中的第一个字节来识别文件类型
  • 累积文件大小
  • 计算 MD5 哈希

在第一个块中的前四个字节之后,我知道该文件是否为 zip 文件。如果是这种情况,我想将文件重定向到完全不同的流。在新流中,压缩文件将被解压缩,然后按照与原始文件相同的概念单独处理。

我怎样才能做到这一点?

原始过程: file.pipe(filePeeker).if(!zipFile).pipe(gZip).pipe(encrypt).pipe(uploadToS3)

解压缩过程 file.pipe(filePeeker).if(zipFile).pipe(streamUnzip).pipeEachNewFile(originalProcess).

谢谢 //迈克尔

【问题讨论】:

    标签: node.js stream


    【解决方案1】:

    有一些模块可以做到这一点,但基本的想法是推送到另一个可读流并在你的条件语句中尽早返回。为它写一个转换流。

    var Transform = require("stream").Transform;
    var util = require("util");
    var Readable = require('stream').Readable;
    
    var rs = new Readable;
    rs.pipe(unzip());
    
    function BranchStream () {
        Transform.call(this);
    }
    util.inherits(BranchStream, Transform);
    
    BranchStream.prototype._transform = function (chunk, encoding, done) {
         if (isZip(chunk)) {
             rs.push(chunk);
             return done()
         }
         this.push(doSomethingElseTo(chunk))
         return done()
    }
    

    【讨论】:

    • 谢谢。在尝试这个之前,我必须阅读更多关于流的信息。我想知道为什么我不能从我的直通流内部这样做: if(isZip) fileStream.unshift(chunk);fileStream.push('');文件流.unpipe(); fileStream.pipe(解压缩)
    • 目前我想这是唯一的方法。模块只是为您抽象这种行为。我猜未来 API 也不会有这样的糖了。
    • 阅读它时,请注意这是一个更高级的 Node.js 主题。很少有人了解 Streams 的来源。但这没关系,因为当你采用这种编程风格时,你就再也不想回去了。
    • 你能推荐任何对我有帮助的模块吗?
    • 我建议使用 Node-core,因为您只会与相应模块的技术作斗争。它不会有太大帮助(我不知道)。一定要阅读 Node 的流文档。你需要的一切都在里面。如果您需要更多示例,请查看 stream-handbook 和这个不错的 blog post
    猜你喜欢
    • 2016-05-09
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多