当前位置: 首页 > 知识库问答 >
问题:

使用Fetch API+Blob API下载文件的内存占用

孙风畔
2023-03-14

Chrome的Blob存储系统设计文档提到了以下内容。

如果blob的内存空间已满,或者新的blob太大而无法在内存中,那么blob系统将使用磁盘。这可以是将旧的blob分页到磁盘,或者直接将新的太大的blob保存到磁盘。

然而,即使在多次浏览文档之后,我仍然有以下担忧:

    null
const download = downloadLinks => {

  const _download = async ( downloadLink ) => {

    const blobURL = await fetch(downloadLink, {  
      responseType: 'blob'  
    })
    .then(res => res.blob())
    .then(blob => window.URL.createObjectURL(blob))
 
    const fileName = downloadLink.substr(downloadLink.lastIndexOf('/'))
    
    const a = document.createElement('a')  
    a.href = blobURL
    a.setAttribute('download', fileName)  
    document.body.appendChild(a)  
    a.click()
    a.remove()  
    
    window.URL.revokeObjectURL(blobURL)
  }

  const downloadInterval = () => {

    if (downloadLinks.length == 0) return

    const url = downloadLinks.pop()
    
    _download(url)
    
    if (downloadLinks.length !== 0) setTimeout(downloadInterval, 500)

  }

  setTimeout(downloadInterval, 0)
}

https://github.com/eligrey/filesaver.js/#supported-browsers

共有1个答案

越源
2023-03-14

简短的回答是肯定的!

>

  • fetch实际上改变了这种行为,因为它首先将数据加载为ReadableStream并加载到内存中。因此,请改用下面的代码。

    此方法可以下载的最大文件大小取决于磁盘大小、操作系统和浏览器。没有一个适用于所有系统的确切数字。这个问题在这里得到了详细解答。

    const download = downloadLinks => {
    
        const _download = url => {
    
            const xhr = new XMLHttpClient()
            xhr.responseType = 'blob'
            xhr.open('GET', url)
            xhr.onload = () => {
                const fileName = url.substr(url.lastIndexOf('/'))
                const blobURL = window.URL.createObjectURL(xhr.response)
                const a = document.createElement('a')  
                a.href = blobURL
                a.setAttribute('download', fileName)  
                document.body.appendChild(a)  
                a.click()
                a.remove()  
                window.URL.revokeObjectURL(blobURL)
            }
            xhr.send(null)
    
        }
    
        const downloadInterval = () => {
    
            if (downloadLinks.length == 0) return
    
            const url = downloadLinks.pop()
            
            _download(url)
            
            if (downloadLinks.length !== 0) setTimeout(downloadInterval, 500)
    
        }
    
        setTimeout(downloadInterval, 0)
    }
    

  •  类似资料:
    • 问题内容: 我正在尝试创建一个文件下载程序作为后台服务,但是当计划了一个大文件时,首先将其放入内存中,然后在下载结束时将文件写入磁盘。 考虑到我可能同时下载许多文件,如何使文件逐渐写入磁盘保留内存? 这是我使用的代码: 问题答案: 我将回调更改为: 这工作得很好。

    • 【内存占用】页面主要展示项目运行过程中内存的使用情况,主要包括以下几个部分: 数据汇总 该项主要展示项目运行过程中的 “总内存峰值”、“堆内存峰值”、“GFX内存峰值” 和 “泄露风险”。其中,总内存为Unity引擎所统计的真实物理内存分配,并不包含系统缓存和第三方库的自身分配内存; 堆内存所指的是 Mono 管理和分配的托管堆内存; GFX内存为用于渲染的资源所占用的内存,主要包括纹理资源、网格

    • 那是外部存储代码,但我想保存在Android手机的内部存储。

    • 我试图使用FetchAPI从一个输入中发布多个文件,但表单数据在附加后仍然为空 我看了看这里,这里,这里,这里和这里的答案,并尝试了他们都没有用 我使用Laravel框架作为后端,这是我的刀片视图文件 控制台记录一个空表单数据对象 这是后端的代码 在其中我得到一个空数组 真的不知道为什么这不起作用!你知道我做错了什么吗?

    • 基于@ari答案的解决方案我已经更新了代码。现在它被优化到只使用1MB(我不知道这是否是将进程分成块的最佳方式,但现在它似乎得到了改进,并且不提供OOM)。我将尝试通过检测可以使用多少堆内存来进一步优化它,但我不确定是否可以实现这一点。直到比这似乎是最好的选择。再次感谢@Ari。

    • 问题内容: 目的是从Internet下载文件,并从中创建文件对象或类似文件的文件,而无需使其接触硬盘驱动器。这仅是出于我的知识,想知道它是否可能或可行,尤其是因为我想看看是否可以绕过必须编写文件删除行的代码。 通常,这就是我从网络上下载内容并将其映射到内存的方式: 问题答案: 这就是我最终要做的。