【问题标题】:Piping got.stream to a file管道 got.stream 到文件
【发布时间】:2020-07-27 06:07:34
【问题描述】:

我正在重构一些在 Node 中使用 http 模块的代码,改为使用 got。我尝试了以下方法:

function get(url, filePath) {
  return new Promise((resolve, reject) => {
    got.stream(url).on
        ("response", response => {
            const newFile = fs.createWriteStream(filePath);
            response.pipe(newFile);
            newFile.on("finish", () => {
              newFile.close(resolve());
            });
            newFile.on("error", err => {
              reject(err);
            });    
        }).on
        ("error", err => {
             reject(err);
        });
  });
}

finish 事件从未触发。文件 (filePath) 使用 0 字节创建。

使用 newFile 的代码块在我使用 Node http 模块时有效。

got.stream 传送到文件的正确方法是什么?

【问题讨论】:

    标签: javascript node.js stream node.js-got


    【解决方案1】:

    根据got() documentation,您希望将流直接通过管道传输到您的文件,如果您使用pipeline() 执行此操作,它将收集错误并报告完成。

    const pipeline = promisify(stream.pipeline);
    const fsp = require('fs').promises;
    
    function get(url, filePath) { 
        return pipeline(
            got.stream(url),
            fs.createWriteStream(filePath)
        );
    }
    
    // usage
    get(...).then(() => {
        console.log("all done");
    }).catch(err => {
        console.log(err);
    });
    

    仅供参考,got.stream() 的重点是返回一个您可以直接用作流的流,并且由于您希望它转到一个文件,您可以将该流通过管道传输到该文件。我使用pipeline() 而不是.pipe(),因为管道具有比.pipe() 更完整的错误处理,尽管在非错误条件下,.pipe() 也可以工作。


    如果出现错误,这是一个清理输出文件的版本:

    function get(url, filePath) { 
        return pipeline(
            got.stream(url),
            fs.createWriteStream(filePath)
        ).catch(err => {
             fsp.unlink(filePath).catch(err => {
                 if (err.code !== 'ENOENT') {
                 // trying to delete output file upon error
                     console.log('error trying to delete output file', err);
                 }
             });
             throw err;
        });
    }
    

    【讨论】:

    • 使用此方法,我在哪里捕获错误,例如 404?
    • @OldGeezer - 这里的get() 函数返回一个承诺,当出现错误时将拒绝。
    • 谢谢。这可行,但是有没有办法在创建 filePath 之前捕获错误?现在即使 url 不存在也会创建一个 0 字节的文件。实际上,我有一系列动作要采取,比如确保目标文件夹存在,否则在发现上游 url 正常后创建它。我之前使用httppipe 的方法允许我在response 事件中完成所有这些操作。
    • @OldGeezer - 它同时做两件事。最好的办法是在出现错误时删除输出文件,因为并非所有错误都出现在请求的开头。管道操作期间也可能出现错误。我在答案中添加了一个示例。
    猜你喜欢
    • 2013-05-25
    • 2012-08-11
    • 2022-01-02
    • 2015-01-08
    • 1970-01-01
    • 2011-01-20
    • 2014-01-31
    • 2014-10-07
    • 2020-09-13
    相关资源
    最近更新 更多