java+大文件断点续传
---解析HTTP MultiPart协议
一. 大文件上传基础描述:
Spring 框架中使用类似CommonsMultipartFile对象处理表二进制文件信息。
缺点:其接收数据包过程完全被封闭在框架内置对象中,直到本次请求信息处理(接收)完毕后,才允许开发人员从接口调取表单及文件内容。上传过程中的进度信息无法访问,无法上传大尺寸文件(比如几百兆以上的大文件二进制信息)。
注:.NET框架中可依靠IHttpModule接口对象达到JAVA框架中Filter的能力,本文不做描述。
普通POST请求协议,见图:
最下方红圈内为本次表单请求信息
Boundary为多段表单信息的分隔符,这里为-----------------------------------7dflaxxxxxxxxxxx
1.2 可实时获取当前传输进度信息
· 当前已接收的字节数
本次请求发起时间
当前进度节点时间
当前进度状态(初始状态,接收数据中,接收数据完毕等)
在Java框架中,公有内存区为ServletContext对象(例,使用setAttribute方法,以键值对的形式将单个用户进度信息存入HashMap对象)。在.NET框架中,公有内存区为HttpApplicationState对象。
二. 问题点分析:
数据包全部加载入内存:对于大文件的MultiPart数据量来说,这种方式会占用大量内存(比如一个用户正在上传1G的数据,那么内存区必须接收到全部1G数据后才能进行解析,如果多用户同时操作会导致服务器崩溃),这种方式不可用。
但这种方式会面临本次接收的分段信息内含有多个表单项信息及剩余的不完整表单信息,或本次接收的分段信息实际上不包含任何表单信息,仅仅是大文件二进制信息的一个片段。所以,这种方式在编码上会带来一定的复杂度。
3.1 项目构成要点
Filter对象:
使用以上两对象,可对本次请求进行按字节流接收。在此可创建比较小的接收缓冲区,依靠BufferedInputStream的read进行分段循环接收。
ProgressInfo对象:
FormPart对于单个Form表单的描述。listFormPart为本次请求的全部表单描述集合。即供后续代码调用的全部表单项内容。
multi-form.jsp页面:
用来显示本次请求的所有表单项信息,包括普通Input表单,及File表单信息。
3.2.1 服务器端:
一般常说的断点续传是指文件下载的断点续传。 即利用HTTP协议中的Content-Range关键字(在HTTP Header中),向服务器发请求,服务器接收请求后,查看Content-Range属性的文件偏移量,从而发送后续文件二进制信息给浏览器。比如网络蚂蚁类的下载软件,即开启多线程利用Content-Range关键字将某个网络资源分布接收,最终整合保存在本地。
在服务器端,也可以依靠对Filter的配置信息,对文件上传信息进行核查或过滤,比如不能上传某些扩展名的文件,文件上传尺寸控制,另存后的文件名唯一性控制等也都需要更细致的描述。
MultiData.txt :一次截获的全部MultiPart数据包信息
MultiForm.java:主过滤器,Filter。用来处理全部上传过程。