前言:

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。

上面的一段话是来自 http://fex.baidu.com/webuploader/  的介绍,现在做的项目需要用到大文件的上传,之前没有做过,现有的jquery的uploadify只用于上传图片什么的小文件,查了网上的资料,这个插件好像对于大文件不是很友好,为了安全起见,使用百度的成熟框架,不论是多文件还是单个的大文件都是很好用的,没有很多的问题,关于webuploader的详细介绍看官网就行:

我的项目是javaweb,开发环境是MyEclipse,页面使用jsp

1、先将 webuploader-0.1.5.zip 这个文件下载下来:https://github.com/fex-team/webuploader/releases

根据个人的需求放置自己需要的东西就行,全部放到项目里也可以,下面是我自己需要的东西:

2、代码部分:分为jsp和servlet部分

1、jsp部分代码:

  1. <script type="text/javascript">
  2. var fileMd5;
  3. //监听分块上传过程中的三个时间点
  4. WebUploader.Uploader.register({
  5. "before-send-file":"beforeSendFile",
  6. "before-send":"beforeSend",
  7. "after-send-file":"afterSendFile",
  8. },{
  9. //时间点1:所有分块进行上传之前调用此函数
  10. beforeSendFile:function(file){
  11. var deferred = WebUploader.Deferred();
  12. //1、计算文件的唯一标记,用于断点续传
  13. (new WebUploader.Uploader()).md5File(file,0,10*1024*1024)
  14. .progress(function(percentage){
  15. $('#item1').find("p.state").text("正在读取文件信息...");
  16. })
  17. .then(function(val){
  18. fileMd5=val;
  19. $('#item1').find("p.state").text("成功获取文件信息...");
  20. //获取文件信息后进入下一步
  21. deferred.resolve();
  22. });
  23. return deferred.promise();
  24. },
  25. //时间点2:如果有分块上传,则每个分块上传之前调用此函数
  26. beforeSend:function(block){
  27. var deferred = WebUploader.Deferred();
  28. $.ajax({
  29. type:"POST",
  30. url:"<%=basePath%>Video?action=checkChunk",
  31. data:{
  32. //文件唯一标记
  33. fileMd5:fileMd5,
  34. //当前分块下标
  35. chunk:block.chunk,
  36. //当前分块大小
  37. chunkSize:block.end-block.start
  38. },
  39. dataType:"json",
  40. success:function(response){
  41. if(response.ifExist){
  42. //分块存在,跳过
  43. deferred.reject();
  44. }else{
  45. //分块不存在或不完整,重新发送该分块内容
  46. deferred.resolve();
  47. }
  48. }
  49. });
  50. this.owner.options.formData.fileMd5 = fileMd5;
  51. deferred.resolve();
  52. return deferred.promise();
  53. },
  54. //时间点3:所有分块上传成功后调用此函数
  55. afterSendFile:function(){
  56. //如果分块上传成功,则通知后台合并分块
  57. $.ajax({
  58. type:"POST",
  59. url:"<%=basePath%>Video?action=mergeChunks",
  60. data:{
  61. fileMd5:fileMd5,
  62. },
  63. success:function(response){
  64. alert("上传成功");
  65. var path = "uploads/"+fileMd5+".mp4";
  66. $("#item1").attr("src",path);
  67. }
  68. });
  69. }
  70. });
  71. var uploader = WebUploader.create({
  72. // swf文件路径
  73. swf: '<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf',
  74. // 文件接收服务端。
  75. server: '<%=basePath%>UploadVideo',
  76. // 选择文件的按钮。可选。
  77. // 内部根据当前运行是创建,可能是input元素,也可能是flash.
  78. pick: {id: '#add_video',   <span style="background-color:rgb(255,204,0);">//这个id是你要点击上传文件的id,自己设置就好</span>
  79. multiple:false},
  80. // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
  81. resize: true,
  82. auto:true,
  83. //开启分片上传
  84. chunked: true,
  85. chunkSize:10*1024*1024,
  86. accept: {
  87. //限制上传文件为MP4
  88. extensions: 'mp4',
  89. mimeTypes: 'video/mp4',
  90. }
  91. });
  92. // 当有文件被添加进队列的时候
  93. uploader.on( 'fileQueued', function( file ) {
  94. $('#item1').empty();
  95. $('#item1').html('<div id="' + file.id + '" class="item">'+
  96. '<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+
  97. '<p class="info">' + file.name + '</p>' +
  98. '<p class="state">等待上传...</p></div>'
  99. );
  100. });
  101. // 文件上传过程中创建进度条实时显示。
  102. uploader.on( 'uploadProgress', function( file, percentage ) {
  103. $('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
  104. });
  105. uploader.on( 'uploadSuccess', function( file ) {
  106. $( '#'+file.id ).find('p.state').text('已上传');
  107. });
  108. uploader.on( 'uploadError', function( file ) {
  109. $( '#'+file.id ).find('p.state').text('上传出错');
  110. });
  111. uploader.on( 'uploadComplete', function( file ) {
  112. $( '#'+file.id ).find('.progress').fadeOut();
  113. });
  114. function start(){
  115. uploader.upload();
  116. $('#btn').attr("onclick","stop()");
  117. $('#btn').text("取消上传");
  118. }
  119. function stop(){
  120. uploader.stop(true);
  121. $('#btn').attr("onclick","start()");
  122. $('#btn').text("继续上传");
  123. }
  124. </script>

2、servlet部分代码:

servlet部分需要两个servlet,一个用于接收分块文件,一个用于合并分块成一个文件:

1、接收分块servlet代码:

  1. @SuppressWarnings("serial")
  2. public class UploadVideo extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  5. throws ServletException, IOException {
  6. // TODO Auto-generated method stub
  7. super.doGet(req, resp);
  8. doPost(req, resp);
  9. }
  10. @SuppressWarnings("unchecked")
  11. public void doPost(HttpServletRequest request, HttpServletResponse response)
  12. throws ServletException, IOException {
  13. DiskFileItemFactory factory = new DiskFileItemFactory();
  14. ServletFileUpload sfu = new ServletFileUpload(factory);
  15. sfu.setHeaderEncoding("utf-8");
  16. String savePath = this.getServletConfig().getServletContext()
  17. .getRealPath("");
  18. String folad = "uploads";
  19. savePath = savePath + "\\"+folad+"\\";
  20. String fileMd5 = null;
  21. String chunk = null;
  22. try {
  23. List<FileItem> items = sfu.parseRequest(request);
  24. for(FileItem item:items){
  25. if(item.isFormField()){
  26. String fieldName = item.getFieldName();
  27. if(fieldName.equals("fileMd5")){
  28. fileMd5 = item.getString("utf-8");
  29. }
  30. if(fieldName.equals("chunk")){
  31. chunk = item.getString("utf-8");
  32. }
  33. }else{
  34. File file = new File(savePath+"/"+fileMd5);
  35. if(!file.exists()){
  36. file.mkdir();
  37. }
  38. File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
  39. FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
  40. }
  41. }
  42. } catch (FileUploadException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. }
  47. }

2、合并分块servlet代码:

  1. @SuppressWarnings("serial")
  2. public class Video extends HttpServlet {
  3. public void doGet(HttpServletRequest request, HttpServletResponse response)
  4. throws ServletException, IOException {
  5. super.doGet(request, response);
  6. doPost(request, response);
  7. }
  8. public void doPost(HttpServletRequest request, HttpServletResponse response)
  9. throws ServletException, IOException {
  10. String savePath = this.getServletConfig().getServletContext()
  11. .getRealPath("");
  12. String folad = "uploads";
  13. savePath = savePath + "\\"+folad+"\\";
  14. String action = request.getParameter("action");
  15. if(action.equals("mergeChunks")){
  16. //合并文件
  17. //需要合并的文件的目录标记
  18. String fileMd5 = request.getParameter("fileMd5");
  19. //读取目录里的所有文件
  20. File f = new File(savePath+"/"+fileMd5);
  21. File[] fileArray = f.listFiles(new FileFilter(){
  22. //排除目录只要文件
  23. @Override
  24. public boolean accept(File pathname) {
  25. // TODO Auto-generated method stub
  26. if(pathname.isDirectory()){
  27. return false;
  28. }
  29. return true;
  30. }
  31. });
  32. //转成集合,便于排序
  33. List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
  34. Collections.sort(fileList,new Comparator<File>() {
  35. @Override
  36. public int compare(File o1, File o2) {
  37. // TODO Auto-generated method stub
  38. if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
  39. return -1;
  40. }
  41. return 1;
  42. }
  43. });
  44. //UUID.randomUUID().toString()-->随机名
  45. File outputFile = new File(savePath+"/"+fileMd5+".mp4");
  46. //创建文件
  47. outputFile.createNewFile();
  48. //输出流
  49. FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
  50. //合并
  51. FileChannel inChannel;
  52. for(File file : fileList){
  53. inChannel = new FileInputStream(file).getChannel();
  54. inChannel.transferTo(0, inChannel.size(), outChnnel);
  55. inChannel.close();
  56. //删除分片
  57. file.delete();
  58. }
  59. outChnnel.close();
  60. //清除文件夹
  61. File tempFile = new File(savePath+"/"+fileMd5);
  62. if(tempFile.isDirectory() && tempFile.exists()){
  63. tempFile.delete();
  64. }
  65. System.out.println("合并成功");
  66. }else if(action.equals("checkChunk")){
  67. //检查当前分块是否上传成功
  68. String fileMd5 = request.getParameter("fileMd5");
  69. String chunk = request.getParameter("chunk");
  70. String chunkSize = request.getParameter("chunkSize");
  71. File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
  72. response.setContentType("text/html;charset=utf-8");
  73. //检查文件是否存在,且大小是否一致
  74. if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){
  75. //上传过
  76. response.getWriter().write("{\"ifExist\":1}");
  77. }else{
  78. //没有上传过
  79. response.getWriter().write("{\"ifExist\":0}");
  80. }
  81. }
  82. }
  83. }

至此,大文件上传的分块和断点就ok了,这也只是我自己的项目需求编写的,这个框架还涵盖很多的内容和功能,需要你自己去研究了,不过都不是很难,你也可以去修改它的css和js文件根据自己的需求。

单文件WebUploader做大文件的分块和断点续传的更多相关文章

  1. php使用WebUploader做大文件的分块和断点续传

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  2. js使用WebUploader做大文件的分块和断点续传

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

  3. java使用WebUploader做大文件的分块和断点续传

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  4. .net使用WebUploader做大文件的分块和断点续传

    ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...

  5. asp.net使用WebUploader做大文件的分块和断点续传

    HTML部分 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.a ...

  6. 使用webuploader实现大文件断点续传

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  7. java读取 500M 以上文件,java读取大文件

    java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...

  8. webUploader实现大文件分片,断点续传

    问题: 公司现在的业务需求是要上传一个大文件,上一次写了一篇博客,做了一个简单的文件上传,支持单文件,大型文件上传 现在对之前的上传进行优化,支持断点续传,秒传功能 上次博客:[http://www. ...

  9. ASP.NET CORE使用WebUploader对大文件分片上传,并通过ASP.NET CORE SignalR实时反馈后台处理进度给前端展示

    本次,我们来实现一个单个大文件上传,并且把后台对上传文件的处理进度通过ASP.NET CORE SignalR反馈给前端展示,比如上传一个大的zip压缩包文件,后台进行解压缩,并且对压缩包中的文件进行 ...

随机推荐

  1. 详解 ASP.NET Core MVC 的设计模式

    MVC 是什么?它是如何工作的?我们来解剖它 在本节课中我们要讨论的内容: 什么是 MVC? 它是如何工作的? 什么是 MVC MVC 由三个基本部分组成 - 模型(Model),视图(View)和控 ...

  2. nowcoder911J 异或的路径

    题目链接 题意 给出一棵树,每条边有边权.求\(\sum\limits_{i=1}^n{f(i,j)}\),\(f(i,j)\)表示从i到j路径的异或和. 思路 \(g_i\)表示从根到\(i\)的异 ...

  3. [原创]浅谈在创业公司对MVP的理解

    [原创]浅谈在创业公司对MVP的理解 目前自已所处的公司类似一个创业平台,我们内部会不断的去孵化不同方向的产品,产品经理经常谈到的一个词就是MVP,所以有必需要去了解下什么是MVP? 1 什么是MVP ...

  4. Postman界面了解

    Postman界面了解 2019年3月21日去面试了一家软件测试,本以为自己对简历上写的技能都熟悉,跳个槽,涨点工资,想象很美好,现实太残忍.当问到做接口测试postman和swagger工具的时候, ...

  5. Android系统HAL基本概念

    1.前言 Android系统硬件抽象层(Hardware Abstraction Layer),简写为HAL,是连接Android Framework与Linux内核设备驱动的重要桥梁.HAL存在的意 ...

  6. vue需求表单有单位(时分秒千克等等)

    需求如下: 问题分析: 因为用elementui组件 el-input 相当于块级元素,后面的单位<span>分</span>会被挤下去,无法在同一水平. 解决方法: 不用它的 ...

  7. 视觉融合定位github

    1. obr_slam有关的非常有用的github链接: https://github.com/Ewenwan/MVision/tree/master/vSLAM/oRB_SLAM2 2. gnss, ...

  8. Hash冲突的解决--暴雪的Hash算法

    Hash冲突的解决--暴雪的Hash算法https://usench.iteye.com/blog/2199399https://www.bbsmax.com/A/kPzOO7a8zx/

  9. vue引入bootstrap、jquery

    在进行vue的学习,项目中需要引入bootstrap.jquery的步骤. 一.引入jQuery 在当前项目的目录下(就是package.json),运行命令 cnpm install jquery ...

  10. Web应急:网站被植入Webshell

    网站被植入webshell,意味着网站存在可利用的高危漏洞,攻击者通过利用漏洞入侵网站,写入webshell接管网站的控制权.为了得到权限 ,常规的手段如:前后台任意文件上传,远程命令执行,Sql注入 ...