代码之家  ›  专栏  ›  技术社区  ›  Gershom Maes

nodejs streams-将错误转换为默认值

  •  0
  • Gershom Maes  · 技术社区  · 7 年前

    我对流媒体很不熟悉。假设我有一个输入流:

    let inputStream = fs.createReadStream(getTrgFilePath());
    

    我将把这个输入传输到一些输出流:

    inputStream.pipe(someGenericOutputStream);
    

    在我看来, getTrgFilePath() 可能无法生成有效的文件路径。这将导致失败,导致没有内容发送到 someGenericOutputStream .

    我该如何设置以便 inputStream 遇到错误时,它会传输一些默认值(例如 "Invalid filepath!" )不是失败?

    例1:

    如果 获取rgfilepath() 无效,以及 一些常规输出流 process.stdout 我想看看 stdout “文件路径无效!”

    例2:

    如果 获取rgfilepath() 无效,以及 一些常规输出流 是的结果 fs.createOutputStream(outputFilePath) ,我希望在 outputFilePath 内容 “文件路径无效!” .

    我对不需要知道特定类型流的解决方案感兴趣 一些常规输出流 是。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Michał Karpacki    7 年前

    ./lib/create-fs-with-default.js

    module.exports = // or export default  if you use es6 modules
        function(filepath, def = "Could not read file") {
            // We open the file normally
            const _in = fs.createReadStream(filepath);
            // We'll need a list of targets later on
            let _piped = [];
            // Here's a handler that end's all piped outputs with the default value.
            const _handler = (e) => {
                if (!_piped.length) {
                    throw e;
                }
    
                _piped.forEach(
                    out => out.end(def)
                );
            };
            _in.once("error", _handler);
    
            // We keep the original `pipe` method in a variable
            const _orgPipe = _in.pipe;
            // And override it with our alternative version...
            _in.pipe = function(to, ...args) {
                const _out = _orgPipe.call(this, to, ...args);
    
                // ...which, apart from calling the original, also records the outputs
                _piped.push(_out);
                return _out;
            }
            // Optionally we could handle `unpipe` method here.
    
            // Here we remove the handler once data flow is started.
            _in.once("data", () => _in.removeListener("error", _handler));
            // And pause the stream again so that `data` listener doesn't consume the first chunk.
            _in.pause();
    
            // Finally we return the read stream
            return _in;
        };
    

    const createReadStreamWithDefault = require("./lib/create-fs-with-default");
    const inputStream = fs.createReadStream(getTrgFilePath(), "Invalid input!");
    // ... and at some point
    inputStream.pipe(someOutput);