首页 > 其他分享 >大文件上传的思路

大文件上传的思路

时间:2023-10-19 15:14:35浏览次数:28  
标签:文件 并发 let file 思路 上传 pool

1.大文件上传的解决思路
1.文件切片:把一个大文件转换成二进制内容,然后按照一个固定的大小对二进制内容进行切割,得到多个小文件,然后循环上传所有的小文件。在js中,文件File对象是Blob对象的子类,可以使用slice()方法完成对文件的切割;
2.文件合并:当所有小文件上传完成,调用接口通知后端把所有的文件按编号进行合并,组成大文件;
3.并发控制:结合Promise.race和异步函数实现,限制多个请求同时并发的数量,防止浏览器内存溢出;
4.断点续传:把所有上传失败的小文件加入一个数组里面,在所有小文件都上传结束(成功和失败都算结束)之后再上传一次上传失败了的小文件,反复执行这一步,直到所有小文件都上传成功,可以通过递归实现。

<input type="file" id="fileInput">
<button id="uploadBtn">上传</button>
<script>
// 设置基地址
axios.defaults.baseURL = 'http://localhost:3000'
let file = null
// 获取文件
document.querySelector('#fileInput').addEventListener('change', e => {
file = e.target.files[0]
})
document.querySelector('#uploadBtn').addEventListener('click', () => {
if (!file) return
// 文件分片
let hash = 0 // 切片序号
let size = 1024 * 50 // 切片大小
let fileArr = []

for (let i = 0; i < file.size; i = i + size) {
fileArr.push({
hash: hash++,
chunk: file.slice(i, i + size)
})
}

// 上传文件,并发控制和断点续传
const uploadFileChunks = async (list) => {
if (list.length === 0) {
await axios({
method: 'get',
url: '/merge',
params: {
filename: file.name
}
})
console.log('上传完成')
return
}
let pool = [] // 并发池
const max = 3 // 并发池异步操作的数量
let failList = [] // 上传失败的文件列表
let finish = 0 // 上传完成的数量

// 遍历文件列表,上传文件
for (let i = 0; i < list.length; i++) {
let item = list[i]
console.log(item)
let formData = new FormData()
formData.append('filename', file.name)
formData.append('hash', item.hash)
formData.append('chunk', item.chunk)

// 上传
let res = axios({
method: 'post',
url: '/upload',
data: formData
})
// 把上传文件的异步操作放入并发池里
pool.push(res)

if (pool.length === max) {
// 每当并发池跑完一个任务,就再塞入一个任务
await Promise.race(pool)
}

res.then(() => {
// 请求成功,从并发池里移除
const index = pool.findIndex(it => it === res)
pool.splice(index, 1)
}).catch(() => {
// 请求失败,从并发池里移除,添加到失败的文件列表
const index = pool.findIndex(it => it === res)
pool.splice(index, 1)
failList.push(item)
}).finally(() => {
finish++
// 如果请求都完成了,递归调用自己,把上传失败的文件列表再上传一次
if (finish === list.length) {
uploadFileChunks(failList)
}
})
}
}
uploadFileChunks(fileArr)
})

</script>
3.小结
上面的代码实现只是一个很简单的大文件上传功能,有很多问题都没有解决,只是提供了一个实现大文件上传的思路。
在工作中要实现大文件上传的话推荐使用目前社区已经存在的一些成熟的大文件上传解决方案,如七牛SDK,腾讯云SDK等

 

参考文章:http://blog.ncmem.com/wordpress/2023/10/19/%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e7%9a%84%e6%80%9d%e8%b7%af/

欢迎入群一起讨论

 

 

标签:文件,并发,let,file,思路,上传,pool
From: https://www.cnblogs.com/songsu/p/17774725.html

相关文章

  • js分片上传&断点续传
    原理js将大文件分成多分,全部上传成功之后,调用合并接口合成文件。如果传输中断,下次上传的时候过滤掉已经上传成功的分片,将剩余的分片上传,成功之后合并文件。前置条件获取uoloadId接口(用于标记分片)分片上传接口合成文件接口(后端自动合成则不需要)查询已上传的分片列表接口(断点......
  • CSV文件的读取与写入
    写入CSV文件save_path='/home/wp/st_detection/download_code/toy.csv'withopen(save_path,'w',newline='')ascsvfile:det_writer=csv.writer(csvfile,delimiter=',',quotechar='|',quoting=csv.QUOTE_MIN......
  • js实现文件切片上传,断点续传
    断点续传:顾名思义,继续上次断开的点,继续上传。思路整理:拿到文件,对文件进行fingerprint=md5(file),得到文件指纹。将指纹保存服务器。切割文件,分段上传,每次上传一段。服务器根据指纹进行索引判断文件上传进度,直到文件的全部片段上传完毕。以下文字没有完整的代码,只有基础......
  • react项目中预览pdf文件
    最近需求,要在b端展示上传的pdf文件。实现方式有很多,记录一下我们最常用的pdf.js//安装"pdfjs-dist":"2.0.402"//引入import*aspdfjsfrom'pdfjs-dist'import*aspdfjsWorkerfrom'pdfjs-dist/build/pdf.worker.entry'//定义初始值letpdfDoc=null;......
  • 使用SyncFavor进行文件同步
    SyncFavor是基于C#开发的免费文件同步工具,运行在windows上,下载链接:https://github.com/bsmith-zhao/sync同步管理界面:批量运行界面: 主从同步示例 下载压缩包解压,双击sync.exe启动同步管理器,可以看到空白的管理界面:点击工具栏的[添加工作区]创建工作区,工作区是一系列......
  • php动态生成海报图片、七牛云上传图片、七牛云打包文件
    场景描述具体业务中遇到了动态生成图片同时保存到七牛云上,然后打包提供下载的问题。常规方案一般保存到服务器上,然后打包下载后删除就可以了,为了节约带宽和服务器资源,算是另辟蹊径了。解决 1.动态生成图片逛了一逛github,最后使用了kkokk/poster的库,相当丝滑。 文档......
  • import { useRouter } from 'next/router'; 在非hooks 文件或组件中使用
    将 import{useRouter}from'next/router';改为 importRouterfrom"next/router";使用: Router.push('/');原来使用 import{useRouter}from'next/router';会导致报错如下  ......
  • WPF 编译出现大量系统文件
    .net版本号:.netframework4.6.1WPF编译后为什么会出现如下的系统文件,本身自带的框架应该是包含这些文件。查看这些DLL的版本都是隶属于4.6.2版本的 详细排查插件,发现某个插件最小支持4.6.2版本,本身是4.6.1,这才出现了许多DLL的原因。解决方法很简单:1.降插件的版本2.......
  • 上传阿里云
    #!/usr/bin/python3importtimeimportthreadingimportsubprocessimportmultiprocessingfrommultiprocessingimportPool#-*-coding:utf-8-*-date_dir='/data/download-decryption/aaa/'mutex=threading.Lock()shared_list=[]defupload_url(url):......
  • javascript之分片上传,断点续传的实际项目实现详解
    首先,我们需要了解什么是分片上传和断点续传。分片上传是将大文件分成多个小块进行上传,每个小块可以独立上传,从而提高上传速度和稳定性。而断点续传是指在上传大文件时,当上传过程中因断网或其他原因中断,再次上传时可以不用重头开始,而是从中断的地方继续上传。接下来是分片上传和......