菜鸡源码,专注精品下载!
当前位置:首页 > 建站教程 > 建站知识

解决大文件分片上传/下载限速问题的方法

发布时间:2024-01-05  栏目:建站知识   浏览:   分类:php教程 大文件上传 分片上传 下载限速 大文件下载

大文件分片上传/下载限速解决方案可以通过限制每个分片的上传/下载速度来实现。具体来说,可以将大文件分成多个较小的分片,然后为每个分片设置一个最大上传/下载速度。这样,即使某个分片的上传/下载速度超过了限制,也不会影响其他分片的上传/下载速度。此外,还可以通过使用流式传输技术来进一步优化大文件的上传/下载速度。流式传输技术允许客户端在下载大文件时一边下载一边播放,从而减少了等待时间和网络拥堵。总之,通过合理的分片和限速策略,可以有效地解决大文件上传/下载过程中的速度问题。

分片上传

将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;

初始化一个分片上传任务,返回本次分片上传唯一标识;

按照一定的策略(串行或并行)发送各个分片数据块;

发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件。

h5 实现部分,h5 部分实现了把文件的分割,在上传中,告诉服务端文件的总片数和当前是第几片,各个临时文件通过 http 请求发送出去

<!doctypehtml><html><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><metahttp-equiv="X-UA-Compatible"content="ie=edge"><title>Document</title><style>#progress{width:300px;height:20px;background-color:#f7f7f7;box-shadow:inset01px2pxrgba(0,0,0,0.1);border-radius:4px;background-image:linear-gradient(tobottom,#f5f5f5,#f9f9f9);}#finish{background-color:#149bdf;background-image:linear-gradient(45deg,rgba(255,255,255,0.15)25%,transparent25%,transparent50%,rgba(255,255,255,0.15)50%,rgba(255,255,255,0.15)75%,transparent75%,transparent);background-size:40px40px;display:inline-block;height:20px;}form{margin-top:50px;}</style></head><body><pid="progress"><spanid="finish"style="width:0%;"progress="0"></span></p><formaction=""><inputtype="file"name="file"id="file"><inputtype="button"value="停止"id="stop"></form><script>varfileForm=document.getElementById("file");varstopBtn=document.getElementById('stop');varupload=newUpload();fileForm.onchange=function(){upload.addFileAndSend(this);}stopBtn.onclick=function(){this.value="停止中";upload.stop();this.value="已停止";}functionUpload(){varxhr=newXMLHttpRequest();varform_data=newFormData();constLENGTH=1024*1024*2;varstart=0;varend=start+LENGTH;varblob;varblob_num=1;varis_stop=0//对外方法,传入文件对象this.addFileAndSend=function(that){varfile=that.files[0];blob=cutFile(file);sendFile(blob,file);blob_num+=1;}//停止文件上传this.stop=function(){xhr.abort();is_stop=1;}//切割文件functioncutFile(file){varfile_blob=file.slice(start,end);start=end;end=start+LENGTH;returnfile_blob;};//发送文件functionsendFile(blob,file){varform_data=newFormData();vartotal_blob_num=Math.ceil(file.size/LENGTH);form_data.append('file',blob);form_data.append('blob_num',blob_num);form_data.append('total_blob_num',total_blob_num);form_data.append('file_name',file.name);xhr.open('POST','http://vnn-admin.cc/Api/sliceUpload',false);xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){console.log(xhr.responseText);}varprogress;varprogressObj=document.getElementById('finish');if(total_blob_num==1){progress='100%';}else{progress=Math.min(100,(blob_num/total_blob_num)*100)+'%';//console.log(progress);//console.log('分割');}progressObj.style.width=progress;vart=setTimeout(function(){if(start<file.size&&is_stop===0){blob=cutFile(file);sendFile(blob,file);blob_num+=1;}else{setTimeout(t);}},1000);}xhr.send(form_data);}}</script></body></html>

服务端

服务端接收上传的文件片,并判断是否为最后一块,如果是就合并文件,删除上传的文件块

/***@Desc:切片上传**@paramRequest$request*@returnmixed*/publicfunctionsliceUpload(Request$request){$file=$request->file('file');$blob_num=$request->get('blob_num');$total_blob_num=$request->get('total_blob_num');$file_name=$request->get('file_name');$realPath=$file->getRealPath();//临时文件的绝对路径//存储地址$path='slice/'.date('Ymd');$filename=$path.'/'.$file_name.'_'.$blob_num;//上传$upload=Storage::disk('admin')->put($filename,file_get_contents($realPath));//判断是否是最后一块,如果是则进行文件合成并且删除文件块if($blob_num==$total_blob_num){for($i=1;$i<=$total_blob_num;$i++){$blob=Storage::disk('admin')->get($path.'/'.$file_name.'_'.$i);//Storage::disk('admin')->append($path.'/'.$file_name,$blob);//不能用这个方法,函数会往已经存在的文件里添加0X0A,也就是\n换行符file_put_contents(public_path('uploads').'/'.$path.'/'.$file_name,$blob,FILE_APPEND);}//合并完删除文件块for($i=1;$i<=$total_blob_num;$i++){Storage::disk('admin')->delete($path.'/'.$file_name.'_'.$i);}}if($upload){return$this->json(200,'上传成功');}else{return$this->json(0,'上传失败');}}

下载限速

通过每秒限制输出的字节

关闭 buffer 缓存

publicfunctionsliceDownload(){$path='slice/'.date('Ymd');$filename=$path.'/'.'周杰伦-黑色幽默[mqms2].mp3';//获取文件资源$file=Storage::disk('admin')->readStream($filename);//获取文件大小$fileSize=Storage::disk('admin')->size($filename);header("Content-type:application/octet-stream");//设定header头为下载header("Accept-Ranges:bytes");header("Accept-Length:".$fileSize);//响应大小header("Content-Disposition:attachment;filename=周杰伦-黑色幽默[mqms2].mp3");//文件名//不设置的话要等缓冲区满之后才会响应ob_end_clean();//缓冲区结束ob_implicit_flush();//强制每当有输出的时候,即刻把输出发送到浏览器\header('X-Accel-Buffering:no');//不缓冲数据$limit=1024*1024;$count=0;//限制每秒的速率while($fileSize-$count>0){//循环读取文件数据$data=fread($file,$limit);$count+=$limit;echo$data;//输出文件sleep(1);}}

当你需要更大速度的时候调整 $limit 的数值即可

相关文章

    无相关信息
评论
建站知识
建站知识
使用技巧
调试安装
运营推广