对于一个大文件,我先将文件分段成1M为单位,将这些文件段放到一个数组。然后一个for循环,同时发送数组长度个ajax请求(当然也可以每次发送5个,10个,浏览器会限制同一时间最大数量)。
后端是multer处理,对于每个分段以该分段md5命名。multer每添加完一个分段到磁盘后,检测是不是上传完毕(后端也维持一个md5数组和一个用来表示某一段是否上传的数组fileSegFlagArr
如[1,1,0,1,0,0]
。这表示上传了3段,还有3段没上传)。然后将fileSegFlagArr
返回给前端。前端上传时检测这个数组,如果数组中某些值为false,就只上传对应的段。后端检测到上传完毕,开始拼接文件。
for(var i = 0; i < md5OfFileSeg.length; i++) {
var segPath = path.resolve(__dirname, '../uploads', `logo-${md5OfFileSeg[i]}.blob`);
var seg = fs.readFileSync(segPath); // r
fs.appendFileSync(targetFile, seg); // a
fs.unlinkSync(segPath);
}
如果一次性分很多段上传,都没有任何问题。后端拼接完后,删除段文件,只剩一个目标文件。
问题在于:分段上传过程中,突然刷新页面。这时候服务器会出现很多段(预期行为)。但是有些段的长度不是1M(默认分段为1M)。这说明只上传了几百k到服务器了,但是在req.file.size
中看到的都是1M,也就是不包括这些文件的(说明multer没处理这些,multer处理完的都是1M的)。
然后继续上传,上传完毕。后端组装完毕。完成的文件出现了。这都没问题。但是除此之外,服务器还有几个分段的文件没有删除,这些文件正是之前刷新页面时只上传了几百k的文件(现在是1M)。这些文件手动删除时会出现"需要计算机管理员提供的权限…"。我很确信这不是权限的问题。当我关闭服务端服务器后,这些文件自动删除了。 我想问为什么之前通过fs.unlinkSync
删不掉这几个文件?我猜测是文件锁的问题,但是我不知道怎么解决?