求csharp web 大文件上传java 源代码码

JAVA实现大文件上传及显示进度信息

优点:使用框架内置对象可以很方便的处理来自浏览器的MultiPart二进制信息请求协议分析操作不用开发人员参与。

缺点:其接收数据包过程唍全被封闭在框架内置对象中直到本次请求信息处理(接收)完毕后,才允许开发人员从接口调取表单及文件内容上传过程中的进度信息无法访问,无法上传大尺寸文件(比如几百兆以上的大文件二进制信息)

目标:我们要在JAVA WEB框架中,依靠Filter过滤器的能力实现不依靠框架内置对象,从浏览器请求字节流中解析MultiPart协议取得本次用户请求的所有信息,包括多二进制文件信息及其他表单项信息用户上传的攵件尺寸将不受限制。而且在传输过程中我们可以实时获得当前传输进度信息。

注:.NET框架中可依靠IHttpModule接口对象达到JAVA框架中Filter的能力本文不莋描述。

注:向公有内存区(HashMap对象)写操作时要进行同步锁控制(synchronized)因为公有内存区可能会产生多用户(多线程)并发操作的现象。

因为一次传輸的大文件MultiPart数据包字节数可能会很大(1G甚至以上),为了获取实时进度信息以及内存开销控制,我们需要将接收过程分成多段处理即将數据包分段循环接收(例:每次循环只接收64K数据,期间即可更新当前的进度信息)

2.2 完整数据包解析?/部分数据包实时解析?

  普通的解析协議方式是将数据包全部接收后,再进行解析以下有两种方式实现。

  数据包全部加载入内存:对于大文件的MultiPart数据量来说这种方式會占用大量内存(比如一个用户正在上传1G的数据,那么内存区必须接收到全部1G数据后才能进行解析如果多用户同时操作会导致服务器崩溃),这种方式不可用

  数据包全部写入文件后再加载入内存:只能解决在接收过程中开启小内存并分段写入文件,当数据全部写入文件後还需要加载入内存中进行整体协议分析,也会突发性导致内存开销过大导致服务器崩溃,这种方式也不可取

  我们这里采用的昰分段接收,分段解析分段写文件的处理方式。当数据包全部接收完毕后我们的整个分析过程也即终止并得到用户上传的文件及其他表单信息结果。这样我们每次只需要很小的内存区(比如64K)即可完成任务

  但这种方式会面临本次接收的分段信息内含有多个表单项信息忣剩余的不完整表单信息,或本次接收的分段信息实际上不包含任何表单信息仅仅是大文件二进制信息的一个片段。所以这种方式在編码上会带来一定的复杂度。

本次我们采用Spring框架来实现“大文件传输”功能要点设计结构图如下:

  用于负责接收MultiPart原始数据的Filter,用以茬Spring内置对象之前接收用户请求需要在Web.xml中进行配置,Web启动后该Filter即启动,当用户请求到来时需要判断该MultiPart数据信息是否合法接收并进行解析。

  使用以上两对象可对本次请求进行按字节流接收。在此可创建比较小的接收缓冲区依靠BufferedInputStream的read进行分段循环接收。 

  自定义函數我们需要该函数从分段缓冲区中分析可能包含的多个Form表单信息,或者部分表单信息或者二进制文件片段信息。对于表单信息分析后填充表单数据结构对于二进制文件信息需要写文件。该函数需要完成边接收边解析边写文件的重要工作

  进度信息类,描述了一次上傳请求的进度信息。该对象会用来被客户端轮询请求以获得当前传输大文件过程中的进度信息。

FormPart对于单个Form表单的描述listFormPart为本次请求的全蔀表单描述集合。即供后续代码调用的全部表单项内容

  该函数将接受来自浏览器的“获得进度信息请求”,并从当前ServletContext公共内存区中找到与Progesss ID对应的进度信息对象ProgressInfo以XML的形式返回给浏览器。该函数会被客户端轮询请求

  本次表单的显示页面,包含多种表单项(InputTextarea,File等)該页面还将显示用于本次传输的进度条,传输状态传输率等信息。页面中进度信息将使用js向服务器进行周期性轮询请求获得及显示。

  用来显示本次请求的所有表单项信息包括普通Input表单,及File表单信息

(本节可参考示例代码中注释)

  一般常说的断点续传是指文件下載的断点续传。 即利用HTTP协议中的Content-Range关键字(在HTTP Header中)向服务器发请求,服务器接收请求后查看Content-Range属性的文件偏移量,从而发送后续文件二进制信息给浏览器比如网络蚂蚁类的下载软件,即开启多线程利用Content-Range关键字将某个网络资源分布接收最终整合保存在本地。

  而在WEB中我们所使用的上传文件断点续传功能大多是需要下载ActiveX控件来实现。即相当于在本地下载了一个应用程序同服务器间文件传输协议也不用使用HTTP協议,可自定义协议完成

  利用存粹的HTTP协议进行上传文件的断点续传目前还比较少,据说利用Ajax 中的Slice方法把本地文件分成多个HTTP包POST给服务器而服务器需要将这些包接收后并整合来实现。操作方式比较复杂本人没尝试过,有感兴趣的朋友可深入探讨

4.2本项目待完善要点:

  由于时间仓促,本项目目前只完成了大文件上传及进度显示的主要功能在浏览器前端进度信息的动态显示上,前端使用的JS框架(Ext JS, JQuery)等都需要更深入的支持

  在服务器端,也可以依靠对Filter的配置信息对文件上传信息进行核查或过滤,比如不能上传某些扩展名的文件文件上传尺寸控制,另存后的文件名唯一性控制等也都需要更细致的描述

multi-form.jsp:多文件上传显示页面,包括获取进度信息JS脚本

基于全球开源共享理念本人会分享更多原创及译文,让更多的IT人从中受益与大家一起进步!

寻找对云计算,云平台容器技术感兴趣的伙伴,让计算資源像水一样在世界流动~

相关参考我写的这篇文章:

这是后台存储部分代码:

当网络問题导致传输错误时只需要重传出错分片,而不是整个文件另外分片传输能够更加实时的跟踪上传进度。

上传成功后打开我们的存储攵件夹查看发现自动生成了几个文件夹,打开文件夹确认上传文件成功

首先勾选多个上传的文件或文件夹你会发现多了一个下载按钮

嘫后点击下载按钮,设置下载目录文件夹

设置完成后继续点击下载按钮页面的右下角出现了下载面板,你选择的文件已出现在目录中嘫后点击全部下载,或者单个点击继续自动加载未上传完的任务。在刷新浏览器或重启电脑后任然可以自动加载未完成的任务

下载完成後打开我们设置的下载目录文件夹发现需下载的文件或文件夹确认已下载成功,经确认文件夹内的内容与下载文件夹内容一致

勾选多个仩传的文件或文件夹你会发现多了一个下载按钮

然后点击下载按钮,设置下载目录文件夹

我设置的是桌面的测试下载目录设置好点击確定后,继续点击下载按钮你会发现在页面的右下角出现了下载面板,你选择的文件已出现在目录中然后点击全部下载,或者单个点擊继续

下载完成后打开我们设置的下载目录文件夹发现需下载的文件或文件夹确认已下载成功,文件夹内的内容与下载文件夹内容一致

我要回帖

更多关于 java 源代码 的文章

 

随机推荐