关键词:
分块上传和断点续传
两个概念
分块上传:文件切成多块,独立传输,上传完成后合并
断点续传:传输暂停或异常中断后,可基于原来进度重传
几点说明:
1、小文件不建议分块上传
2、可以并行上传,并且可以无序传输
3、分块上传可以极大提高传输效率,不过要注意分块上传文件的数量
4、减少传输失败后重试的流量及时间
流程:
1、云端初始化上传文件的信息
2、客户端执行上传分块—>上传取消,查询上传信息
3、客户端通知云端上传完成
服务架构:
redis缓存用于云端与客户端文件信息交互
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5PJcYLvX-1641174946216)(E:\\学习笔记\\Go笔记\\截图\\屏幕截图 2022-01-02 095031.png)]
分块上传通用接口
1、初始化分块信息
2、上传分块
3、通知上传完成
4、取消上传分块
5、查看分块上传的整体状态
前期准备
在src下创建cache,在cache目录下再创建Redis,在Redis目录下创建conn.go
import(
"fmt"
"github.com/garyburd/redigo/redis"
"time"
)
var(
pool*redis.Pool//redis连接池用于客户端与redis交互数据
redisHost="127.0.0.1:6379"//redis的IP
redisPass="testupload"//redis登录密码
)
func newRedisPool()*redis.Pool//初始化redis
return&redis.Pool
MaxIdle:50,//最大存储文件信息数
MaxActive:30,//最多实际存储文件信息数
IdleTimeout:300*time.Second,//超过该时间断开与redis的连接
Dial:func()(redis.Conn,error)
//1.打开连接
c,err:=redis.Dial("tcp",redisHost)
if err!=nil
fmt.Println(err)
return nil,err
//2.访问认证
if _,err=c.Do("AUTH",redisPass);err!=nil
c.Close()
return nil,err
return c,nil
,
//定时检查redis的健康状况,若出问题则在客户端关闭redis的连接
TestOnBorrow:func(conn redis.Conn,t time.Time)error
if time.Since(t)<time.Minute
return nil
_,err:=conn.Do("PING")
return err
,
func init()
pool=newRedisPool()//创建redis调用new方法初始化
func RedisPool()*redis.Pool//向外暴露redis连接池否则pool对象无法被外部访问
return pool
1、初始化分块信息
import (
"fmt"
"math"
"net/http"
"rgo/src/util"
"strconv"
rPool"rgo/cache/redis"
"time"
)
//初始化信息
type MultipartUploadInfo struct
FileHash string
FileSize int
UploadID string //唯一标识
ChunkSize int //分块大小
ChunkCount int //分块个数
func InitialMultipartUpload(w http.ResponseWriter,r*http.Request)
r.ParseForm()
username:=r.Form.Get("username")
filehash:=r.Form.Get("filehash")
filesize,err:=strconv.Atoi(r.form.Get("filesize"))
if err!=nil
w.Write(util.NewRespMsg(-1,"params invalid",nil).JSONBytes())
return
//2。获得redis的一个连接
rConn:=rPool.RedisPool().Get()
defer rConn.Close()
//3.生成分块上传的初始化信息
upInfo:=MultipartUploadInfo
FileHash:filehash,
FileSize:filesize,
UploadID:username+fmt.Sprintf("%x",time.Now().UnixNano()),
ChunkSize:5*1024*1024,//5MB
ChunkCount:int(math.Ceil(float64(filesize)/(5*1024*1024))),
//4.将初始化信息写入到redis缓存
rConn.Do("HEST","MP_"+upInfo.UploadID,"chunkcount",upInfo.ChunkCount)
rConn.Do("HEST","MP_"+upInfo.UploadID,"filehash",upInfo.FileHash)
rConn.Do("HEST","MP_"+upInfo.UploadID,"filesize",upInfo.FileSize)
//5.将响应初始化数据返回到客户端
w.Write(util.NewRespMsg(0,"OK",upInfo).JSONBytes())
2.上传文件分块
//上传文件分块
func UploadPartHandler(w http.ResponseWriter,r*http.Request)
//1.解析用户请求参数
r.ParseForm()
username:=r.Form.Get("username")
uploadID:=r.Form.Get("uploadid")
chunkIndex:=r.Form.Get("index")
//2.获得redis连接池中的一个连接
rConn:=rPool.RedisPool().Get()
defer rConn.Close()
//3.获得文件句柄,用于存储分块内容
fpath:="/data/"+uploadID+"/"+chunkIndex
os.MkdirAll(path.Dir(fpath),0744)
if err!=nil
w.Write(util.NewrESPmSG(-1,"Upload part failed",nil).JSONBytes())
return
defer fd.Close()
buf:=make([]byte,1024*1024)
for
n,err:=r.Body.Read(buf)
fd.Write(buf[:n])
if err!=nil
break
//4.更新redis缓存状态
rConn.Do("HEST","MP_"+uploadID,"chkid_"+chunkIndex,1)
//5.返回处理结果到客户端
w.Write(util.NewrESPmSG(0,"OK",nil).JSONBytes())
3.合并
//通知上传合并接口
func CompleteUploadHandler(w http.ResponseWriter,r*http.Request)
//1.解析请求参数
r.ParseForm()
upid:=r.Form.Get("uploadid")
username:=r.Form.Get("username")
filehash:=r.Form.Get("filehash")
filesize:=r.Form.Get("filesize")
filename:=r.Form.Get("filename")
//2.获得redis连接池中的一个连接
rConn:=rPool.RedisPool().Get()
defer rConn.Close()
//3.通过uploadid查询redis并判断是否所有分块上传完成
data,err:=redis.Values(rConn.Do("HGETALL","MP_"+upid))
if err!=nil
w.Write(util.NewRespMsg(-1,"complete upload failed",nil).JSONBytes())
return
totalCount:=0
chunkCount:=0
for i:=0;i<len(data);i+=2
k:=string(data[i].([]byte))
v:=string(data[i+1].([]byte))
if k=="chunkcount"
totalCount,_:=strconv.Atoi(v)
else if strings.HasPrefix(k,"chkid")&& v=="1"
chunkCount++
if totalCount!=chunkCount
w.Write(util.NewRespMsg(-2,"invalid request",nil).JSONBytes())
return
//4.合并分块
//5.更新唯一文件表及用户文件表
fsize,_:=strconv.Atoi(filesize)
dblayer.OnFileUploadFinished(filehash,filename,int(fsize),"")
dblayer.OnUserFileUploadFinished(username,filehash,filename,int64(fsize))
//6.响应处理结果
w.Write(util.NewRespMsg(0,"OK",nil).JSONBytes())
i(filesize)
dblayer.OnFileUploadFinished(filehash,filename,int(fsize),"")
dblayer.OnUserFileUploadFinished(username,filehash,filename,int64(fsize))
//6.响应处理结果
w.Write(util.NewRespMsg(0,“OK”,nil).JSONBytes())
断点续传和分块上传
#pragmamark 异步上传-(void)uploadObjectAsync:(NSString*)FileURLobjectKey:(NSString*)objectKey{ OSSPutObjectRequest*put=[OSSPutObjectRequestnew]; NSLog(@"objectKeyis%@",objectKey 查看详情
项目难点——断点续传分片上传(代码片段)
...一次性上传成功,那么这个时候我们就需要将大文件分块,分成一小块一小块的,然后结合端点续传技术,实现大文件上传。2断点续传2.1概念通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足... 查看详情
java使用webuploader做大文件的分块和断点续传
需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制。第一步:前端修改由于项目使用的是BJUI前端框架,并... 查看详情
超大文件上传和断点续传的源代码
...,当传输的文件比较大时,http协议自动会将文件切片(分块),但这不是我们现在说的重点,我们要做的事是保证在网络中断后1G的文件已上传的那部分在下次网络连接时不必再重传。所以我们本地在上传的时候,要将大文件进... 查看详情
http断点续传(分块传输)
简述断点续传:指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传/下载,如果碰到网络故障,可以从已经上传/下载的部分开始继续上传/下... 查看详情
面试官:请你实现一个大文件上传和断点续传(代码片段)
...一段时间整理了下思路,那么究竟该如何实现一个大文件上传,以及在上传中如何实现断点续传的功能呢?本文将从零搭建前端和服务端,实现一个大文件上传和断点续 查看详情
一文搞懂分片上传和断点续传(代码片段)
〝古人学问遗无力,少壮功夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这... 查看详情
一文搞懂分片上传和断点续传(代码片段)
〝古人学问遗无力,少壮功夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这... 查看详情
web大文件分块上传断点续传demo
一、概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载。在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了。一般断点下载时才用到Range和Content-Range实体头。HTTP协议本身不支持断... 查看详情
ios大文件分片上传和断点续传
...,当传输的文件比较大时,http协议自动会将文件切片(分块),但这不是我们现在说的重点,我们要做的事是保证在网络中断后1G的文件已上传的那部分在下次网络连接时不必再重传。所以我们本地在上传的时候,要将大文件进... 查看详情
electron中实现大文件上传和断点续传功能(代码片段)
Electron官网的描述:Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的。从官... 查看详情
超大文件上传和断点续传的源代码
...,当传输的文件比较大时,http协议自动会将文件切片(分块),但这不是我们现在说的重点,我们要做的事是保证在网络中断后1G的文件已上传的那部分在下次网络连接时不必再重传。所以我们本地在上传的时候,要将大文件进... 查看详情
基于http的文件断点续传实现(代码片段)
...现1:断点续传的介绍客户端软件断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以... 查看详情
php断点续传之文件上传与文件下载(代码片段)
下载:<?php/**php下载类,支持断点续传*Date:2013-06-30*Author:fdipzone*Ver:1.0**Func:*publicdownload:下载文件*publicsetSpeed:设置下载速度*privategetRange:获取header中Range*/classFileDownload//classstartprivate$_speed=512;// 查看详情
webuploader与django进行断点续传,大文件上传(代码片段)
需要实现的效果如下需要使用的 jsjquery.jswebuploader.hshashmap.js路由fromdjango.urlsimportpathfrom.importviewsurlpatterns=[path('index/',views.index),path('checkChunk/',views.checkChunk,name= 查看详情
springboot实现分片上传断点续传大文件极速秒传-备忘(代码片段)
文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进行上传,这可不是一个好的办法,毕竟很少有人会忍受,当文件上传... 查看详情
搭建fastdfs服务,及单机redis服务,springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传文件和批量上传(代码片段)
前言搭建单机redis服务,结合fastdfs,springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传。技术采用:webuploader+springboot+redis+fastdfs(服务端)+FastDFS_Client。本文所需实现工具,皆在此包中https://download. 查看详情
使用js实现可断点续传的文件上传方案(代码片段)
刚开始学习前端开发就碰到文件上传问题,还要求可断点续传。查了很多资料,发现H5的fileAPI刚好可以满足我们的需求,也遇到了一些问题,于是记录下来为有同样需求的朋友提供一些帮助。一、首先,为了引入文件对象,我们... 查看详情