【问题标题】:Why am I getting the error "Error [ERR_STREAM_WRITE_AFTER_END]: write after end" when downloading a file?为什么在下载文件时出现错误“错误 [ERR_STREAM_WRITE_AFTER_END]:结束后写入”?
【发布时间】:2019-10-30 06:45:11
【问题描述】:

我正在尝试使用 url 将存储在 azure blob 存储中的文件下载到各个 blob。

我正在下载五个 blob 文件,并且我确实拥有所有这些 blob 文件的单独 url。

下面是我的代码:

function Download()
{
  const fs = require('fs');
  const path = require('path');
  const https = require('https');
  const url = require('url');

  var sasToken = '?sv=2019-02-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2019-10-3xxxxxxxZ&sp=rl'
  var blobUris = ['https:xxx', 'xxx', 'xxx', 'xxx', 'xxx'];

  var i;
  for(i=0; i<blobUris.length; i++)
  {
    var sasUrl = blobUris[i] + sasToken;
    var filename=url.parse(blobUris[i]).pathname.split('/').pop();
    var filePath = "D:/BLESensor"
    var file = fs.createWriteStream(filePath+"/"+filename)
    var request = https.get(sasUrl, function(response) {
      response.pipe(file);
        //  Promise.resolve()
        //  .then(() => file.destroy())
        //  .catch(console.log)
  });
}

  }
return Download();

当我运行该函数时出现以下错误:

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_stream_writable.js:248:12)
    at WriteStream.Writable.write (_stream_writable.js:296:5)
    at IncomingMessage.ondata (_stream_readable.js:709:20)
    at IncomingMessage.emit (events.js:198:13)
    at IncomingMessage.Readable.read (_stream_readable.js:504:10)
    at flow (_stream_readable.js:973:34)
    at resume_ (_stream_readable.js:954:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
    at errorOrDestroy (internal/streams/destroy.js:107:12)
    at WriteStream.onerror (_stream_readable.js:733:7)
    at WriteStream.emit (events.js:203:15)
    at errorOrDestroy (internal/streams/destroy.js:107:12)
    at writeAfterEnd (_stream_writable.js:250:3)
    at WriteStream.Writable.write (_stream_writable.js:296:5)
    [... lines matching original stack trace ...]
    at flow (_stream_readable.js:973:34)

任何建议将不胜感激。谢谢!

【问题讨论】:

  • 这里没有足够的信息,但我怀疑你会在学习 JavaScript 中的异步编程基础知识后解决你的问题。

标签: javascript node.js http download


【解决方案1】:

这是因为我们在 for 循环中下载,而 https.get 调用(与所有 Node.js I/O 调用一样)是异步的。因此,在这种情况下,response.pipe 将无法正常工作(因为文件流将在 response.pipe 被调用时关闭)与函数范围的文件变量(例如 var file..)

这个问题有一个简单的解决方法,我们只需要确保文件变量是block scoped,例如为此使用letconst

function Download()
{
  const fs = require('fs');
  const path = require('path');
  const https = require('https');
  const url = require('url');

  var sasToken = '?sv=2019-02-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2019-10-3xxxxxxxZ&sp=rl'
  var blobUris = ['https:xxx', 'xxx', 'xxx', 'xxx', 'xxx'];

  var i;
  for(i=0; i<blobUris.length; i++)
  {
    var sasUrl = blobUris[i] + sasToken;
    var filename=url.parse(blobUris[i]).pathname.split('/').pop();
    var filePath = "D:/BLESensor"
    // Make sure file variable is block scoped. We could use const too.. but not var!
    let file = fs.createWriteStream(filePath+"/"+filename)
    console.log("Downloading file: " + (i+1));
    var request = https.get(sasUrl, function(response) {
        response.pipe(file);
    });
  }

}

return Download();

【讨论】:

    猜你喜欢
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多