【问题标题】:How can i save a file i download using fetch with fs我如何保存使用fetch with fs下载的文件
【发布时间】:2022-12-18 03:11:07
【问题描述】:

我尝试使用 github 的 fetch() 函数下载文件。
然后我尝试将获取的文件 Stream 保存为带有 fs-module 的文件。
这样做时,我收到此错误:

TypeError [ERR_INVALID_ARG_TYPE]:“transform.writable”属性必须是 WritableStream 的一个实例。接收到 WriteStream 的实例

我的问题是,我不知道 WriteStream 和 WritableStream 之间的区别或如何转换它们。

这是我运行的代码:

async function downloadFile(link, filename = "download") {
    var response = await fetch(link);
    var body = await response.body;
    var filepath = "./" + filename;
    var download_write_stream = fs.createWriteStream(filepath);
    console.log(download_write_stream.writable);
    await body.pipeTo(download_write_stream);
}

Node.js:v18.7.0

【问题讨论】:

    标签: node.js download stream fs


    【解决方案1】:

    好问题。网络流是新事物,它们是处理流的不同方式。 WritableStream 告诉我们可以创建可写流如下:

    import {
      WritableStream
    } from 'node:stream/web';
    
    const stream = new WritableStream({
      write(chunk) {
        console.log(chunk);
      }
    });
    

    然后,您可以创建一个自定义流写每个块到磁盘。一个简单的方法可能是:

    const download_write_stream = fs.createWriteStream('./the_path');
    
    
    const stream = new WritableStream({
      write(chunk) {
        download_write_stream.write(chunk);
      },
    });
    
    async function downloadFile(link, filename = 'download') {
      const response = await fetch(link);
      const body = await response.body;
      await body.pipeTo(stream);
    }
    

    【讨论】:

    • 你有没有解释为什么你不能body.pipeTo(process.stdout)?您创建 WritableStream 并在内部调用 process.stdout.write 的示例有效,但为什么有必要?在其他地方stdin.pipe(stdout) 有效——readable.pipeTo() 有什么不同?
    【解决方案2】:

    您可以使用 Readable.fromWebbody(来自 web streams APIReadableStream)转换为可与 fs 方法一起使用的 NodeJS Readable 流。

    请注意,readable.pipe 会立即返回另一个流。要等待它完成,您可以使用 stream.finished 的承诺版本将其转换为 Promise,或者您可以为 'finish''error' 事件添加侦听器以检测成功或失败。

    const fs = require('fs');
    const { Readable } = require('stream');
    const { finished } = require("stream/promises");
    
    async function downloadFile(link, filepath = "./download") {
        const response = await fetch(link);
        const body = Readable.fromWeb(response.body);
        const download_write_stream = fs.createWriteStream(filepath);
        await finished(body.pipe(download_write_stream));
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-03
      • 2021-12-24
      • 1970-01-01
      • 2022-01-15
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      相关资源
      最近更新 更多