标签归档:文件分块

HTTP文件分块上传下载

在开发中经常需要上传下载文件,涉及web页面,手机应用,线下服务器等,文件传输方式有HTTP,FTP,BT。。于是基于HTTP开发了统一文件上传下载接口。
由于上传涉及多端,网络状况复杂,需要能够支持断点续传,因此需要对文件进行分块和校验。
请求上传:

  • chunk:当前块编号
  • chunks:文件分块总数
  • md5:整个文件md5
  • content:文件块内容
  • size:文件块大小

服务端返回:

  • statu:状态,0失败,非0成功
  • chunk:需要上传的块编号
  • message:操作信息

服务端有几种情况

  • 1. 上传成功,md5已经存在,说明文件已存在,则返回上传成功,并结束上传,类似秒传
  • 2. 上传成功,md5已经不存在,但当前文件块已经存在,说明该文件已经上传过一部分,则返回成功,并给出需要开始上传的块号,类似断点续传
  • 3. 上传成功,文件块不存在,当前块号小于总块数减一,则返回上传成功,并给出下一块块号
  • 4. 上传成功,文件块不存在,当前块号等于总块数减一,进行合并,校验成功,则返回上传成功,并结束上传
  • 5. 上传成功,文件块不存在,当前块号等于总块数减一,进行合并,校验成功,则返回上传失败,从第一块重新开始上传
  • 6. 上传失败,服务端返回失败,则根据错误信息重传
  • 7. 上传失败,服务端没有返回,则重传当前块

客户端依据自定义的大小对文件进行切割,每次传递一个块,当服务端接收到当前块号为总块数减一则认为全部上传完毕,进行文件块合并,清除临时文件块,计算MD5,如果MD5与传递过来的相等则认为上传成功,否则失败,要求客户端从第一块重传。
这个是基于客户端顺序上传的,假如是并发上传呢?那么就需要在每个分块上传结束后触发合并,需要借助锁来管理。
又拍云表单分块上传则分为3步骤:

  • 1.初始化,上报文件信息
  • 2.上传分块
  • 3.上传结束,触发合并

百度的WebUploader则支持浏览器向服务端的断点续传,利用HTML5或Flash对文件进行分块,计算MD5。
HTTP分块下载,也就是断点续传下载,是根据HTTP1.1协议(RFC2616)中定义的HTTP头 Range和Content-Range字段来控制的:

  • 1. 客户端在HTTP请求头里面指明Range,即开始下载位置
  • 2. 服务端在HTTP响应头里面返回Content-Range,告知下载其实点和范围

服务端可以将文件MD5等加入Etag或自定义Header字段里面,HTTP客户端便可以分开请求数据,最后合并;否则永远都是从头开始。其实也可以把大文件切成多个小文件,再一个个下载回来合并。
有些web服务器直接支持文件上传和下载的断点续传,比如Nginx。

刚才的文件分块传输过程,有点像TCP通信,也有建立连接,分片,校验,重发,断开连接。
而这个将大任务分解为多个小任务进行处理的思想,即准备–>循环(并行)处理–>结束,可以应用到很多项目里面,比如大数据,爬虫。为Web管理系统写了jQuery插件用来处理的耗时任务,将一个耗时任务分解为多个循环请求,避免超时

  • 1. prepare:服务端返任务标示ID,总步骤,及附加参数
  • 2. process:根据返回参数进行循环请求
  • 3. complete:循环完成,触发结束

后面又延伸出另外一个插件,支持任意顺序步骤的处理。

参考链接:
聊聊大文件上传
md5 javascript
HTTP协议--断点续传
http断点续传的秘密
nginx-upload-module模块实现文件断点续传
通过curl测试服务器是否支持断点续传