- 浏览: 164052 次
- 性别:
- 来自: 重庆
博客专栏
-
Angularjs实战
浏览量:19419
文章分类
- 全部博客 (98)
- 工具 (2)
- 字符编码问题 (1)
- 微信开发调试工具 (2)
- java (10)
- spring (2)
- mybatis (2)
- spring boot (2)
- 其他 (1)
- spring ajax (1)
- jquery (4)
- 中间件 (3)
- oracle数据库 (2)
- oracle (1)
- 文件上传 (1)
- AngularJS (23)
- css (4)
- js (9)
- Iconfont (1)
- 个人 (1)
- WebLogic (4)
- maven (2)
- 转载 (1)
- File (2)
- webupload (4)
- tomcat (2)
- linux (2)
- Jersey (11)
- 脚本 (1)
- ftp (1)
- xdata (1)
- 钉钉 (1)
- 文档转换 (3)
- ionic (1)
- vue (2)
最新评论
-
masuweng:
java批量将多文件打包成zip格式 -
柳絮飞祭奠:
// 读取错误执行的返回流 是这个 B ...
java调用执行cmd指令启动weblogic -
109:
您好,我想知道在startServer怎么判断它是错误执行的流 ...
java调用执行cmd指令启动weblogic -
williamfan:
dataSourceConfig.getUrl()这个可以直接 ...
spring boot和mybatis入门
当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度。多的不说了直接怼代码
前端是三个监听:一个是获取md5,一个是分片,最后一个是合并代码
<!DOCTYPE html> <html ng-app="uploadApp" ng-controller="uploadCtl"> <head> <title>fileupload.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="../themes/reset.css" type="text/css"></link> <link rel="stylesheet" href="../themes/webuploader.css" type="text/css"></link> <script type="text/javascript" src="../plugins/jquery-3.2.0.min.js"></script> <script type="text/javascript" src="../plugins/webuploader.min.js"></script> <script type="text/javascript"> $(function(){ var fileName; var fileMd5; //监听分块上传过程中的三个时间点 WebUploader.Uploader.register({ "before-send-file":"beforeSendFile", "before-send":"beforeSend", "after-send-file":"afterSendFile", },{ //时间点1:所有分块进行上传之前调用此函数 beforeSendFile:function(file){ fileName=file.name; var deferred = WebUploader.Deferred(); //1、使用md5计算文件的唯一标记,用于断点续传 (new WebUploader.Uploader()).md5File(file,0,10*1024*1024) .progress(function(percentage){ $('#item1').find("p.state").text("正在读取文件信息..."); }) .then(function(val){ fileMd5=val; $('#item1').find("p.state").text("成功获取文件信息..."); //获取文件信息后进入下一步 deferred.resolve(); }); //调用deferred.resolve();无效 return deferred.promise(); }, //时间点2:如果有分块上传,则每个分块上传之前调用此函数 beforeSend:function(block,file){ console.log("分块"+fileName.replace(/.+\./, "")); var deferred = WebUploader.Deferred(); $.ajax({ type:"POST", url:"/servlet/mergeFile?action=checkChunk", data:{ //文件唯一标记 fileMd5:fileMd5, //当前分块下标 chunk:block.chunk, //当前分块大小 chunkSize:block.end-block.start }, dataType:"json", success:function(response){ if(response.ifExist){ //分块存在,跳过 deferred.reject(); }else{ //分块不存在或不完整,重新发送该分块内容 deferred.resolve(); } } }); this.owner.options.formData.fileMd5 = fileMd5; deferred.resolve(); return deferred.promise(); }, //时间点3:所有分块上传成功后调用此函数 afterSendFile:function(){ console.log("合并") ; //如果分块上传成功,则通知后台合并分块 $.ajax({ type:"POST", url:"/servlet/mergeFile?action=mergeChunks", data:{ fileMd5:fileMd5, }, success:function(response){ alert("上传成功"); var path = "uploads/"+fileMd5+".mp4"; $("#item1").attr("src",path); } }); } }); var uploader = WebUploader.create({ // swf文件路径 swf: '<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf', // 文件接收服务端。 server: '/servlet/FileUpLoad', // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: {id: '#picker', //这个id是你要点击上传文件的id,自己设置就好</span> multiple:true}, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize: true, auto:true, //上传并发数 threads:5, //开启分片上传 chunked: true, chunkSize:10*1024*1024, /* accept: { //限制上传文件为MP4 extensions: 'mp4', mimeTypes: 'video/mp4', } */ }); // 当有文件被添加进队列的时候 uploader.on( 'fileQueued', function( file ) { $('#item1').empty(); $('#item1').html('<div id="' + file.id + '" class="item">'+ '<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+ '' + '<p class="state">等待上传...</div>' ); }); // 文件上传过程中创建进度条实时显示。 uploader.on( 'uploadProgress', function( file, percentage ) { $('#item1').find('p.state').text(file.name+'上传中 '+Math.round(percentage * 100) + '%'); }); uploader.on( 'uploadSuccess', function( file ) { $( '#'+file.id ).find('p.state').text('已上传'); }); uploader.on( 'uploadError', function( file ) { $( '#'+file.id ).find('p.state').text('上传出错'); }); uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('.progress').fadeOut(); }); function start(){ uploader.upload(); $('#btn').attr("onclick","stop()"); $('#btn').text("取消上传"); } function stop(){ uploader.stop(true); $('#btn').attr("onclick","start()"); $('#btn').text("继续上传"); } }); </script> </head> <body> <div id="uploader" class="wu-example"> <!--用来存放文件信息--> <div id="thelist" class="uploader-list"></div> <div class="btns"> <div id="picker">选择文件</div> <button id="ctlBtn" class="btn btn-default">开始上传</button> </div> </div> <div id="item1"></div> </body> </html>
后端:一个保持文件servlet,一个判断分片和合并文件servelt
保持文件servlet
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Path; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @Path("/fileupload") public class ZFileCommand extends HttpServlet{ private static final long serialVersionUID = -2720014423604662780L; // 1.文件上传路径 private static final String UPLOAD_DIRECTORY = "D:/文件上传"; // 2.设置临时存储文件大小,当超过大小时,将先存储超出大小文件在临时目录 private static final int MEMORY_THRESHOLD = 1024 * 1024 * 30; // 3.设置最大文件上传值 private static final int MAX_FILE_SIZE = 1024 * 1024 * 2000; // 4.最大请求值 private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 2048; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //获取文件名 String filename=request.getParameter("name"); //防止读取name名乱码 filename=new String(filename.getBytes("iso-8859-1"),"utf-8"); //在控制台打印文件名 System.out.println("文件名:"+filename); //设置文件MIME类型 response.setContentType(getServletContext().getMimeType(filename)); //设置Content-Disposition String realName = filename.substring(filename.indexOf("_")+1); response.setHeader("Content-Disposition", "attachment;filename="+realName); //输入流为项目文件,输出流指向浏览器 InputStream is=new FileInputStream(UPLOAD_DIRECTORY+filename); ServletOutputStream os =response.getOutputStream(); /* * 设置缓冲区 * is.read(b)当文件读完时返回-1 */ int len=-1; byte[] b=new byte[1024]; while((len=is.read(b))!=-1){ os.write(b,0,len); } //关闭流 is.close(); os.close(); } /** * @摘要 提供文件上传的方法 */ public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { //1.设置字符编码为utf-8 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 2.检测是否为多媒体上传 if (!ServletFileUpload.isMultipartContent(request)) { // 2.1如果不是则停止 PrintWriter writer = response.getWriter(); writer.println("Error: 表单必须包含 enctype=multipart/form-data"); writer.flush(); return ; } // 3.配置上传参数 DiskFileItemFactory factory = new DiskFileItemFactory(); //4. 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中 factory.setSizeThreshold(MEMORY_THRESHOLD); // 5.设置临时存储目录 java.io.tmpdir默认的临时文件路径为服务器的temp目录 factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); // 6.设置最大文件上传值 upload.setFileSizeMax(MAX_FILE_SIZE); // 7.设置最大请求值 (包含文件和表单数据) upload.setSizeMax(MAX_REQUEST_SIZE); //8. 如果目录不存在则创建 File uploadDir = new File(UPLOAD_DIRECTORY); if (!uploadDir.exists()) { uploadDir.mkdir(); } String fileMd5 = null; String chunk = null; try { // 10.解析请求的内容提取文件数据 List<FileItem> formItems = upload.parseRequest(request); // 10.1迭代表单数据 if (formItems != null && formItems.size() > 0) { for (FileItem item : formItems) { if (item.isFormField()) { String fieldName = item.getFieldName(); if(fieldName.equals("fileMd5")){ fileMd5 = item.getString("utf-8"); } if(fieldName.equals("chunk")){ chunk = item.getString("utf-8"); } }else{ String nFileName = new File(item.getName()).getName(); File file = new File(UPLOAD_DIRECTORY+"/"+fileMd5); if(!file.exists()){ file.mkdir(); } nFileName=nFileName.substring(0,nFileName.lastIndexOf(".")) ; item.write(new File(UPLOAD_DIRECTORY+"/"+fileMd5+"/"+chunk)); item.delete(); } } } } catch (Exception ex) { PrintWriter writer=response.getWriter(); writer.print("error"); } } }
一个判断分片和合并文件servelt
import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class mergeFile extends HttpServlet { private static final long serialVersionUID = 1L; private static final String UPLOAD_DIRECTORY = "D:/文件上传"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { super.doGet(request, response); doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String savePath = this.getServletConfig().getServletContext() .getRealPath(""); String folad = "uploads"; savePath = "D:/文件上传"; String action = request.getParameter("action"); if(action.equals("mergeChunks")){ //合并文件 //需要合并的文件的目录标记 String fileMd5 = request.getParameter("fileMd5"); //读取目录里的所有文件 File f = new File(savePath+"/"+fileMd5); File[] fileArray = f.listFiles(new FileFilter(){ //排除目录只要文件 public boolean accept(File pathname) { // TODO Auto-generated method stub if(pathname.isDirectory()){ return false; } return true; } }); //转成集合,便于排序 List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray)); Collections.sort(fileList,new Comparator<File>() { public int compare(File o1, File o2) { // TODO Auto-generated method stub if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){ return -1; } return 1; } }); //UUID.randomUUID().toString()-->随机名 File outputFile = new File(savePath+"/"+fileMd5+".mp4"); //创建文件 outputFile.createNewFile(); //输出流 FileChannel outChnnel = new FileOutputStream(outputFile).getChannel(); //合并 FileChannel inChannel; for(File file : fileList){ inChannel = new FileInputStream(file).getChannel(); inChannel.transferTo(0, inChannel.size(), outChnnel); inChannel.close(); //删除分片 file.delete(); } outChnnel.close(); //清除文件夹 File tempFile = new File(savePath+"/"+fileMd5); if(tempFile.isDirectory() && tempFile.exists()){ tempFile.delete(); } System.out.println("合并成功"); }else if(action.equals("checkChunk")){ //检查当前分块是否上传成功 String fileMd5 = request.getParameter("fileMd5"); //分块次数 String chunk = request.getParameter("chunk"); //分块大小 String chunkSize = request.getParameter("chunkSize"); File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk); response.setContentType("text/html;charset=utf-8"); //检查文件是否存在,且大小是否一致 if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){ //上传过 response.getWriter().write("{\"ifExist\":1}"); }else{ //没有上传过 response.getWriter().write("{\"ifExist\":0}"); } } }
附件:源码
- Angular.zip (1.3 MB)
- 下载次数: 28
相关推荐
在Web开发中,文件上传是一项常见的功能,而百度Web Uploader是一个强大的JavaScript库,专为实现高效的多文件上传而设计。它支持预览、断点续传、多线程上传等功能,极大地提升了用户体验。本示例将详细介绍如何在...
3. **文件分片**:分片上传是实现断点续传的基础,WebUploader将大文件拆分成多个小块(如2MB或4MB),每个块作为一个单独的请求发送到服务器。这种方式不仅方便了断点续传,还能够实现并行上传,加速整体上传速度。...
WebUploader是百度开发的一款JavaScript组件,它允许用户进行大文件的分片上传。分片上传是指将大文件分割成多个小块(片),每个片单独上传,提高了上传速度和成功率。WebUploader还支持断点续传,即如果上传过程...
`vue-simple-uploader` 是一个适用于 Vue3 的轻量级文件上传组件,它允许开发者方便地实现文件上传功能,包括大文件的分片上传。在对源码进行深入分析之前,我们先来理解一下大文件分片上传的基本原理。 大文件分片...
在处理大文件上传时,为了实现最佳性能并确保可靠性,通常会采用分片上传和断点续传技术。本文将详细解析这两种技术以及如何在MinIO中实现它们,并提供前后端的示例代码。 分片上传: 1. **分片原理**:当上传大...
- **分片上传**:对于大文件,Uploader组件可以将其分割成多个小块进行并发上传,提高上传速度,并在服务器端进行重组。 - **进度条显示**:通过监听上传过程中的事件,展示文件上传进度,提升用户体验。 - **错误...
本文介绍如何使用PHP结合Web Uploader插件实现大文件的分片上传功能。重点在于提升上传大文件的效率,通过将大文件分割成多个小块(分片)并发上传,从而克服网络不稳定和超时的问题。本文适用于对Web开发中的文件...
Web Uploader通过JavaScript实现了一套完整的文件上传机制,使得开发者可以自定义上传界面、控制上传流程,甚至实现跨域上传和大文件分片上传。 Web Uploader的主要功能和特点包括: 1. **多文件选择**:允许用户...
在这个"webuploader完整例子\百度切割上传"中,我们主要探讨的是如何实现大文件的分片上传(切割上传)以及后端处理这些分片并合并成原始文件的技术细节。 1. **WebUploader的基本概念** WebUploader的核心理念是...
总的来说,这个项目涵盖了SpringBoot、MinIO集成、文件服务组件的设计与实现、前端Vue.js的使用以及分片上传等技术,是学习和实践现代Web应用开发的一个良好示例。通过这个项目,开发者不仅可以掌握文件存储服务的...
5. **上传策略**:Web Uploader支持分片上传和断点续传,这对于处理大文件尤其有用。开发者可以设置每片文件的大小,并在断网或中断后继续未完成的上传。 6. **图片处理**:对于图片上传,Web Uploader还提供了预览...
接着,我们引入Redis作为临时存储,实现文件分片上传。文件被分割成多个小块(chunk),每个chunk在上传时被暂时存储在Redis中。这样做的好处在于,Redis是内存数据库,读写速度极快,适合处理大量的小文件操作。每...
百度WebUploader是一款强大的前端文件上传组件,它提供了一套完整的解决方案,包括文件选择、文件预览、上传进度显示、多文件上传、断点续传等功能。在本文中,我们将深入探讨WebUploader的核心特性、API用法以及...
2. **分片上传**:对于大文件,WebUploader可以将其切割成多个小块进行上传,这样即使在网络不稳定的情况下,也能通过断点续传保证文件完整上传。 3. **进度显示**:在上传过程中,WebUploader可以实时显示每个文件...
在现代Web应用中,用户可能需要一次性上传多个文件,例如图片、文档或视频。这个过程如果能实时显示每个文件的上传进度,将极大地提升用户体验。本文将深入探讨如何实现"多文件上传,并显示每一个的进度"这一功能,...
1. **分片并发上传**:Web Uploader将大文件分割成多个小分片并行上传,一旦某个分片上传失败,只需重新上传出错的分片,无需重新上传整个文件。这显著提升了上传速度,并且能实时跟踪上传进度。 2. **预览与压缩**...
Vue2.0结合webuploader实现文件分片上传功能 本文主要介绍了如何使用Vue2.0结合webuploader实现文件分片上传功能,解决大文件上传的问题。下面是相关知识点的详细说明: 文件分片上传的必要性 在上传大文件时,...
尤其在处理大文件上传时,WebUploader提供了分片上传的功能,以提高上传效率并降低网络中断的风险。本文将详细讲解如何使用WebUploader实现分片上传,并将其与后端服务进行分离,确保前后端职责明确。 首先,让我们...