局域网超大文件上传

文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦、缺乏交互、用户体验差。

一、前端代码

英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用HTML5的API,对文件上传进行渐进式增强:

    * iframe上传
   * ajax上传
   * 进度条
   * 文件预览
   * 拖放上传

1.1 传统形式

  文件上传的传统形式,是使用表单元素file,参考 http://www.ruanyifeng.com/blog/2012/08/file_upload.html :

  <form id="upload-form" action="upload.php" method="post" enctype="multipart/form-data" >
    <input type="file" id="upload" name="upload" /> <br />
    <input type="submit" value="Upload" />
  </form>

所有浏览器都支持上面的代码,点击上传按钮后,网页"锁死",用户只能等待上传结束,然后浏览器刷新,跳到表单的action属性指定的网址。

1.2 iframe上传

  用户点击submit时,动态插入一个iframe元素

var form = $("#upload-form");

  form.on(‘submit‘,function() {

    // 此处动态插入iframe元素

  });

  var seed = Math.floor(Math.random() * 1000);

  var id = "uploader-frame-" + seed;

  var callback = "uploader-cb-" + seed;

  var iframe = $(‘<iframe id="‘+id+‘" name="‘+id+‘" >‘);

  var url = form.attr(‘action‘);

  form.attr(‘target‘, id).append(iframe).attr(‘action‘, url + ‘?iframe=‘ + callback);

1.3 ajax上传

  HTML5提出了XMLHttpRequest对象的第二版,从此ajax能够上传文件了。这是真正的"异步上传",是将来的主流。

form.on(‘submit‘,function() {

    // 此处进行ajax上传

});

 // 检查是否支持FormData

  if(window.FormData) { 

    var formData = new FormData();

    // 建立一个upload表单项,值为上传的文件

    formData.append(‘upload‘, document.getElementById(‘upload‘).files[0]);

    var xhr = new XMLHttpRequest();

    xhr.open(‘POST‘, $(this).attr(‘action‘));

    // 定义上传完成后的回调函数

    xhr.onload = function () {

      if (xhr.status === 200) {

        console.log(‘上传成功‘);

      } else {

        console.log(‘出错了‘);

      }

    };

    xhr.send(formData);

  }

1.4 进度条

  XMLHttpRequest第二版还定义了一个progress事件,可以用来制作进度条。

//在页面中放置一个HTML元素progress

<progress id="uploadprogress" min="0" max="100" value="0">0</progress>

//定义进度progress事件的回调函数

 xhr.upload.onprogress = function (event) {

    if (event.lengthComputable) {

      var complete = (event.loaded / event.total * 100 | 0);

      var progress = document.getElementById(‘uploadprogress‘);

      progress.value = progress.innerHTML = complete;

    }

}

二、后端

  Spring 框架中使用类似CommonsMultipartFile对象处理表二进制文件信息,细心地会发现在利用框架下封装的Multiform接口进行文件上传时,会先把文件传输至tomcat一个指定的work目录之下,然后再传输到指定的路径。小文件上传这个时间延迟基本上可以忽略,但是在大文件上传时,这个上传的速度就很让人头疼,上传过程中的进度信息无法访问。

  因此我们有必要从浏览器请求字节流中解析Multiform协议,实现不依靠框架内置对象,取得用户请求的所有数据,同时,用户上传的大小不受限制,而且在传输过程中,我们可以实时获取传输进度。

参考https://www.cnblogs.com/darkprince/p/5114936.html

2.1 普通Post请求协议及MultiPart协议

  因为一次传输的大文件MultiPart数据包,字节数可能会很大(1G甚至以上),为了获取实时进度信息,以及内存开销控制,我们需要将接收过程分成多段处理,即将数据包分段循环接收(例:每次循环只接收64K数据,期间即可更新当前的进度信息)。本次我们采用Spring框架来实现“大文件传输”功能,要点设计结构图如下:

2.2 源码解析

Filter对象:

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

ServletInputStream/BufferedInputStream对象:

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

getBoundarySectFromBuf()函数:

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

ProgressInfo对象:

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

FormPart对象及listFormPart集合:

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

Controller层getProgInfo()处理函数:

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

详细代码可以参考:http://blog.ncmem.com/wordpress/2019/08/12/java实现大文件上传/

欢迎入群一起讨论“374992201”

原文地址:https://www.cnblogs.com/songsu/p/12582340.html

时间: 2024-08-29 15:01:05

局域网超大文件上传的相关文章

求超大文件上传方案( csharp )

HTML部分 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="up6.index" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xh

求超大文件上传方案( WebUploader )

文件夹数据库处理逻辑 public class DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); this.root.put("f_id", ""); this.root.put("f_nameLoc", "根目录"); this.root.put("f_pid", ""); thi

JavaScript超大文件上传

随着视频网站和大数据应用的普及,特别是高清视频和4K视频应用的到来,超大文件上传已经成为了日常的基础应用需求. 但是在很多情况下,平台运营方并没有大文件上传和断点续传的开发经验,往往在网上找一些简单的PHP或者Java程序来实现基本的上传功能,然而在实际使用中会发现,这些基于脚本语言实现的上传功能模块性能很弱,一是不支持2GB以上的内容上传:二是无法支持断点续传:三是效率极低,单台服务器最多支持几十个并发上传连接. 当前我们要搭建一个运营级的视频服务平台,在尝试了各种产品均无法满足要求,因此最后

超大文件上传到Azure Linux虚拟机最佳实践

客户在实际进行迁移的时候,往往碰到需要将本地数据中心的超大文件,比如单个200GB的文件,或者总共1TB的无数文件上传到Azure上的情况,尤其是传到Azure的Linux虚拟机的场景,这种场景包括: 大日志文件上传到Azure进行分析 数据库备份文件导入导出 大数据文件下载到本地等等 尤其是要将数据库备份文件导入到Linux虚拟机进行数据库恢复,一般用户常常会选择传统的FTP方式进行处理,这样的方式通常会花费用户十几个小时,甚至几天的时间进行文件传输,但是在云计算的时代,其实有非常多的工具和方

超大文件上传(web应用---SSH框架)

struts提供的上传文件功能,文件太大就报错. 需要解决超大文件(几个G)上传的问题.断点续传的功能. 技术选型,查百度之后.最终选择了这个stream插件. stream官方资料地址:http://www.twinkling.cn/ 去下载源码.源码地址.项目源码托管在git.oschina.net,地址:http://git.oschina.net/jiangdx/stream 解压安装包之后,在eclipse中导入此项目.(注,这是一个Maven项目,服务器用的是tomcat 不是jet

Spring MVC环境中文件上传大小和文件类型限制以及超大文件上传bug问题

    在上一篇文章中,主要介绍了Spirng MVC环境下的正常情况下文件上传功能实现.在实际开发的时候,还会涉及到上传文件大小和类型的限制,接下来就会对Spirng MVC环境下文件上传大小和类型的限制进行介绍,还会讲解到文件上传大小tomcat服务器bug问题及解决方案. 一.文件上传大小限制 这里还是接着上篇文章先介绍Spring MVC下的文件上传大小限制,文件上传大小的限制在springmvc-config.xml中配置文件解析器CommonsMultipartResolver时即可

求超大文件上传方案( jsp )

1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通过浏览器上传至服务器,做一层中转便可以实现,但当这份文件非常大到了10GB级别,我们就需要思考另一种形式的技术方案了,也就是本文要阐述的方案. 技术要求主要有以下几方面: 支持超大数据量.10G级别以上 稳定性:除网络异常情况100%成功 准确性:数据无丢失,读写准确性100% 效率:1G文件分钟级

4GB以上超大文件上传和断点续传服务器的源码

最近遇见一个需要上传超大大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表格数据.上传影音文件等.如果文件体积比较大,或者网络条件不好时,上传的时间会比较长(要传输更多的报文,丢包重传的概率也更大),用户不能刷新页面,只能耐心等待请求完成. 下面从文件上传方式入手,整理大文件上传的思路,并给出了相关实例代码,由于PHP内置了比较方便的文件拆分和拼接方法,因此服务端代码使用

超大文件上传方案(B/S)

javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id="postForm" action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data"> <