【问题标题】:Fetch blob from URL and write to file从 URL 获取 blob 并写入文件
【发布时间】:2018-12-28 21:45:36
【问题描述】:

我正在尝试fetch来自服务器的一些二进制数据(MP3),然后将其存储在一个文件中:

var fs = require ('fs');
var fetch = require ('node-fetch');

fetch (
   audioUrl,
   {
      method: 'GET',
      headers: { 'Accept': '*/*' }
   }
)
.then ((res) => res.blob())
.then ((blob) => {
    console.log ('Blob size: ', blob.size);

    fs.writeFile (
        `filename.mp3`,
        blob,  // BUG HERE
        (err) => {
            if (err) {
                console.log (`Error writing audio ${audioIdx}`, err);
            }
        }
    );
})

问题标记在BUG HERE。我将一个 blob 传递给 fs,它不理解 blob,只写 [object Blob]。我还尝试了以下方法:

blob                                // writes [object Blob]
new Uint8Array (blob)               // writes empty file
Buffer.from (new Uint8Array (blob)) // writes empty file
new Buffer (blob, 'binary')   // Error: argument is not a Buffer

以上都不起作用。如何正确地做到这一点?

请注意,我在调用writeFile 之前记录了blob.sizeblob.size 显示正确的大小,所以 fetch 似乎成功了。

【问题讨论】:

  • 您使用的是哪个 fetch 库?
  • 节点获取。我会更新问题。

标签: node.js blob fs fetch-api


【解决方案1】:

好的,所以从MDN Docs 开始,Blob 不是缓冲区,这是写入文件系统所需要的。

我认为从响应中获取缓冲区可能会更好,例如:

.then(res => res.buffer())
.then(/* write your file here */)

尽管取决于文件的大小,您最好的选择可能是完全跳过 .writeFile 函数并改为管道流。

【讨论】:

    【解决方案2】:

    您可以使用fs.createWriteStream 将响应流式传输到文件。

    fetch(
        audioUrl,
        {
            method: 'GET',
            headers: { 'Accept': '*/*' }
        }
    ).then(res => {
        new Promise((resolve, reject) => {
            const dest = fs.createWriteStream(`filename.mp3`);
            res.body.pipe(dest);
            res.body.on('end', () => resolve());
            dest.on('error', reject);
        })
    });
    

    【讨论】:

    • 这比.buffer().arrayBuffer() 好(至少对于大文件)
    【解决方案3】:

    简单且有效(在 nodejs 中使用 Buffer API)

    const fetch = require('node-fetch');
    const Buffer = require('buffer').Buffer 
    const fs = require('fs');
    fetch("https://example.com/file.mp3", {
      "headers": {},
      "method": "GET"
    }).then(function(resp) {
        return resp.blob();
    }).then(async function(blob) {
        var buffer = await blob.arrayBuffer();
        buffer = Buffer.from(buffer)
        fs.createWriteStream('file.mp3').write(buffer);
    })
    

    【讨论】:

      猜你喜欢
      • 2018-12-30
      • 2018-08-07
      • 2019-07-04
      • 2012-09-01
      • 2012-08-06
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多