背景: 最近在看大佬分享写的分片上传解析,想更深入的理解自己试着实现试试,发现有挺多细节上的问题的。分片上传原理上就是把文件流,按照自己的算法,分成一片一片然后上传到服务器
目标: 完成基本的可设置片的大小,完成分片上传
遇到的问题: 以前用new formData 比较少,formData是不能直接输出的,foreach能一个个输出,append是插入的 setValue可设置当前的同名称下的数据 像是set
uploadChunkNum = Math.ceil(fileSize / uploadChunkSize)for(let chunkI = 1;chunkI <= uploadChunkNum;chunkI++)
{
uploadChunk = file.slice(chunkStart , chunkEnd)
if(uploadChunk.size > 0){
uploadData.set('chunk' , uploadChunk)
uploadData.set('fileName' , fileName)
uploadData.set('hash' , chunkI)
chunkStart = chunkEnd + 1
chunkEnd = uploadChunkSize * parseInt(chunkI + 1) + 1
}}先根据参数配置 设置的分片的大小然后算出分片数,然后开始从0开始切割。
根据分片数开始循环,因为设置的上传分片数大小是一致的,每次开始的头部是上一次的切割结束的尾部加1 , 每次开始的尾部就是参数设置的大小 * 循环的第几次 + 1(最后一次可能并不是正好那么大的,不过blob二进制会自动切割到最大的位置 )
接下来是node搭建的服务端,采用的是express multipart 解析提交的multipt/data 数据 然后fs-extra 把每个上传暂存的文件转移到指定的目录下
const multipart = new multiparty.Form();
multipart.parse(req, async (err, fields, files) => {
if (err) { return; }
const [chunk] = files.chunk;
const [hash] = fields.hash;
const [filename] = fields.fileName;
const chunkDir = `${UPLOAD_DIR}/${filename}`; // 切片目录不存在,创建切片目录
if (!fse.existsSync(chunkDir)) {
await fse.mkdirs(chunkDir);
} // fs-extra 专用方法,类似 fs.rename 并且跨平台 // fs-extra 的 rename 方法 windows 平台会有权限问题 // https://github.com/meteor/meteor/issues/7852#issuecomment-255767835
await fse.move(chunk.path, `e://js-worker//uploadChunkBackend//tmp//${hash}`);
res.end("received file chunk");});待完成: 只完成到了上传分片成功的步骤 , 接下来继续研究下如何node服务端把文件融合起来生成想要的文件
总结: 有些东西光知道原理是不够了 , 开始去试着写一个类似的功能才发现实现一个简单的都并不是那么的容易,有很多东西要学。学无止境,加油!