文件上传之切片

       今天主要讲讲文件切片,主要在上传大文件的时候需要用到,你想想,上传一个几百兆的大视频,但网络带宽又特别感人,一个不小心就报错造成上传失败,那是什么感受...

       进入正题,选择文件后,点击“确定”,首先计算出文件总大小,然后需要做什么呢,你需要告诉服务器这个大文件被切成了多少片,还得在每次上传的时候告诉它当前是第几片。最好加一个Date.now(),不然大家同时上传一个1.jpg,一到服务器就重名了,加了Date.now(),1_(时间戳).jpg就不会重名了。

       每次上传的Blob对象使用file.slice(start, end)完成:


注意红框标注的地方,每次上传都需要执行formData['delete'](fileName),至于原因已经在里面加入了,自己看哈。

下面是上传进度和上传速度的代码:

var xhr = ZUtil.getXHR(),
formData = new FormData(),
// 上次的时间戳
prev = new Date().getTime(),
// 以上传
load = 0,
// 文件大小
size = file.size,
translateSize = ZUtil.translateByte(size),
prevProgress = 0,
$bar = $row.find('.z-progress-bar'),
$progress = $row.find('.z-upload-progress'),
$speed = $row.find('.z-upload-speed'),
$progressLinear = $row.find('.z-upload-progress-linear');
formData.append('uniqueFlag', Date.now());
formData.append('fileName', file.name);
xhr.addEventListener('error', uploadError, false);
xhr.upload.addEventListener('progress', function(e) {
// e.loaded是本次请求已经上传的文件大小
var loaded,
// 当前时间戳
now = new Date().getTime(),
distance = now - prev;
if (splitUpload) {
/**
* 如果是分片上传,e.loaded是每次的file.slice(start, end),理论上就是每份文件切片大小
* 而不会像整体文件上传一样,e.loaded是从0慢慢增长到file.size
* 需要加上load才是已经上传的文件大小
*/
loaded = e.loaded + load;
} else {
loaded = e.loaded;
}
var progress = Math.min(Math.round(loaded / size * 100), 100);
/**
* 每次更新的时间间隔 >= speedUpdateInterval
* 或者上传完毕(如果是分片上传,那么e.loaded >= splitSize也意味着当前分片文件上传完成)
*/
if(distance >= speedUpdateInterval || (progress == 100 || (splitUpload && e.loaded >= splitSize))) {
var speed = ZUtil.translateByte((loaded - load) / distance * 1000);
$speed.html('速度:' + speed + '/s');
prev = now;
load = loaded;
}
if(progress != prevProgress) {
prevProgress = progress;
$progress.html('进度:' + progress + '% of ' + translateSize);
$progressLinear.css({
width : progress + '%'
});
}

下面是文件上传效果:

第一个切片:


最后一个切片:


大家也看到了,文件只有216KB,我设置的切片大小只有0.01MB,所以才会上传22次。


        onreadystatechange代码


       可以看到,每次需要后端返回success,并且当前切片index < 总切片数totalIndex才会继续上传,如果全部上传完毕,会调用afterUpload回调方法

后端java代码


       通过对比index和totalIndex,如果相同,就合并文件

       上一篇已经提过如果不适用切片,仅仅一个进度条,这都是骗人的。使用切片后,分片上传文件,等到上一片文件上传成功后才会继续上传下一片,因为公司没有要求使用数据库记录切片信息,所以每次上传切片后没有将切片文件信息保存到数据库,要是哪个切片上传失败了,只能重新上传...这样做虽然花费的时间长了一点(当然了,这么多次请求,HTTP握手肯定很费时间的),不过这样也是值得的,几百兆的大文件重复上传更费时间呢,反正还是需要开发者自己权衡,个人建议,几兆的小文件就别用切片了,麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值