技术体系:html5(formdata) + java + servlet3.0+maven + tomcat7

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>大文件切割上传</title>
<style>
#wrap{width:600px; height:400px; border:1px solid #ccc; margin:10px auto;} </style>
</head>
<body>
<p>文件上传:<input type="file" id="file" onchange="uploadFile(this);"></p>
</body>
</html>
<script>
function uploadFile(file){
var File = file.files[0];
var totalSize = File.size; //文件总大小
var splitSize = 10 * 1024 * 1024; //10M 切割文件大小
var len = Math.ceil(totalSize/splitSize);
var fileName = File.name;
var xhr = new XMLHttpRequest();
var isLast = false;
var step = Math.ceil(100/len);
for(var i = 0 ; i< len;i++){
blob = File.slice(i*splitSize,splitSize*(i+1));
isLast = (i == len-1) ? true:false;
var result = upload(blob,i);
console.log("上传结果:" + result);
} function upload(blob,index){
var formData = new FormData();
formData.append("index",index);
formData.append("fileName",fileName);
formData.append("isLast",isLast);
formData.append("splitSize",splitSize);
formData.append("file",blob);
xhr.open("POST", "ajax4.do",false);
xhr.send(formData);
return xhr.responseText;
} } </script>

后台代码:

 package com.sgepit.ajax;

 import java.io.IOException;

 import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part; @WebServlet("/ajax4.do")
@MultipartConfig
public class Ajax4 extends HttpServlet { final String uploadPath = "D:/uploadFile/"; @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String index = req.getParameter("index");
String fileName = req.getParameter("fileName");
String isLast = req.getParameter("isLast");
String splitSize = req.getParameter("splitSize");
splitSize = null == splitSize ? "0" : splitSize; int size = Integer.parseInt(splitSize); Part part = req.getPart("file");
try {
if(null != part && part.getSize() != 0){
StringBuffer sbRealPath = new StringBuffer();
sbRealPath.append(uploadPath).append(index).append(".").append("part");
//写入文件
part.write(sbRealPath.toString());
if("true".equals(isLast)){ //如果是最后一次加载,准备合并文件
FileUtil fileUtil = new FileUtil();
fileUtil.mergePartFiles(uploadPath, ".part", size, uploadPath+fileName);
Thread.sleep(3000); //睡眠3秒以后再删除
fileUtil.deleteSplitFiles(uploadPath,".part");
}
resp.getWriter().write("success");
}
} catch (Exception e) {
e.printStackTrace();
} } }

工具方法:

 package com.sgepit.ajax;

 import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; /**
* 文件处理辅助类
*
*/
public class FileUtil { /**
* 获取指定目录下特定文件后缀名的文件列表(不包括子文件夹)
* @param dirPath 目录路径
* @param suffix 文件后缀
* @return
*/
public static ArrayList<File> getDirFiles(String dirPath,final String suffix) {
File path = new File(dirPath);
File[] fileArr = path.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowerName = name.toLowerCase();
String lowerSuffix = suffix.toLowerCase();
if (lowerName.endsWith(lowerSuffix)) {
return true;
}
return false;
} });
ArrayList<File> files = new ArrayList<File>(); for (File f : fileArr) {
if (f.isFile()) {
files.add(f);
}
}
return files;
} /**
* 合并文件
*
* @param dirPath 上传文件所在的目录名称
* @param partFileSuffix 拆分文件后缀名
* @param partFileSize拆分文件的字节数大小
* @param mergeFileName 合并后的文件名
* @throws IOException
*/
public void mergePartFiles(String dirPath, String partFileSuffix,
int partFileSize, String mergeFileName) throws IOException {
ArrayList<File> partFiles = FileUtil.getDirFiles(dirPath, partFileSuffix);
Collections.sort(partFiles, new FileComparator()); RandomAccessFile randomAccessFile = new RandomAccessFile(mergeFileName,"rw");
randomAccessFile.setLength(partFileSize * (partFiles.size() - 1)
+ partFiles.get(partFiles.size() - 1).length());
randomAccessFile.close(); ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
partFiles.size(), partFiles.size() * 3, 1, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(partFiles.size() * 2)); for (int i = 0; i < partFiles.size(); i++) {
threadPool.execute(new MergeRunnable(i * partFileSize,mergeFileName, partFiles.get(i)));
}
} /**删除临时文件
* @param dirPath
* @param partFileSuffix
*/
public void deleteSplitFiles(String dirPath,String partFileSuffix){
ArrayList<File> partFiles = FileUtil.getDirFiles(dirPath, partFileSuffix);
for (int i = 0; i < partFiles.size(); i++) {
partFiles.get(i).delete();
} } /**
* 根据文件名,比较文件 ,根据文件名排序
*/
private class FileComparator implements Comparator<File> {
public int compare(File o1, File o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
} /**
* 合并处理Runnable
*
*/
private class MergeRunnable implements Runnable {
long startPos;
String mergeFileName;
File partFile; public MergeRunnable(long startPos, String mergeFileName, File partFile) {
this.startPos = startPos;
this.mergeFileName = mergeFileName;
this.partFile = partFile;
} public void run() {
RandomAccessFile rFile;
try {
rFile = new RandomAccessFile(mergeFileName, "rw");
rFile.seek(startPos);
FileInputStream fs = new FileInputStream(partFile);
byte[] b = new byte[fs.available()];
fs.read(b);
fs.close();
rFile.write(b);
rFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

备注:一定要注意,在maven环境下,启动tomcat的时候,一定要用tomcat7:run, 而不是tomcat:run,否则无法正常使用。(踩坑了)

Ajax+Java实现大文件切割上传的更多相关文章

  1. java springboot 大文件分片上传处理

    参考自:https://blog.csdn.net/u014150463/article/details/74044467 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时 ...

  2. 支持IE低版本的上传 大文件切割上传 断点续传 秒传

    1. http://files.cnblogs.com/files/blackice/UploadDemo.rar 此demo是使用的 swfupload 2.http://download.csdn ...

  3. AJAX-----16HTML5实现大文件切割上传

    2点多接了个电话导致失眠,没办法,跑起来接着板砖了...... 废话不多说,直接走码... <!DOCTYPE html> <html lang="en"> ...

  4. java http大文件断点续传上传

    因为需要研究下断点上传的问题.找了很久终于找到一个比较好的项目. 效果: 上传中,显示进度,时间,百分比. 点击[Pause]暂停,点击[Resume]继续. 2,代码分析 项目进行了封装使用最简单的 ...

  5. AJAX大文件切割上传以及带进度条。

    分块传输的原理就是利用HTML5新增的文件slice截取函数. 代码如下: html: <input id="f" type="file" name=&q ...

  6. vue大文件分片上传插件

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  7. Hadoop如何将TB级大文件的上传性能优化上百倍?

    这篇文章,我们来看看,Hadoop的HDFS分布式文件系统的文件上传的性能优化. 首先,我们还是通过一张图来回顾一下文件上传的大概的原理. 由上图所示,文件上传的原理,其实说出来也简单. 比如有个TB ...

  8. 利用blob对象实现大文件分片上传

    首先说分片上传,我们在进行文件上传的时候,因为服务器的限制,会限制每一次上传到服务器的文件大小不会很大,这个时候我们就需要把一个需要上传的文件进行切割,然后分别进行上传到服务器. 假如需要做到这一步, ...

  9. js实现大文件分片上传的方法

    借助js的Blob对象FormData对象可以实现大文件分片上传的功能,关于Blob和FormData的具体使用方法可以到如下地址去查看FormData 对象的使用Blob 对象的使用以下是实现代码, ...

随机推荐

  1. 编译Caffe-Win错误集锦

    Caffe在Windows下编译还是遇到不少麻烦的... 1.visual studio 2013 error C2371: 'int8_t' : redefinition; 引入的unistd.h文 ...

  2. POJ_3020_最小路径覆盖

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8721   Accepted: 4330 ...

  3. The as! Operator

    Prior to Swift 1.2, the as operator could be used to carry out two different kinds of conversion, de ...

  4. 【转载】JSTL和EL的使用

    使用JSTL前的准备 想要使用JSTL,首先需要给工程导入JSTL的包(JSTL.jar和standard.jar). JSTL标签库 在JSTL中分为以下五个标签 核心标签 格式化标签 SQL标签 ...

  5. python学习之小小爬虫

    学习python一段时间了,写了一个图片的小小爬虫,分享下,不喜勿喷! #coding=utf-8 ''' Created on 2015-5-22 @author: 悦文 ''' import re ...

  6. Linux基础:uniq命令总结

    本文只总结一些常用的用法,更详细的说明见man uniq和 uniq --help. uniq命令 uniq命令主要用于去重. 需要注意的是,不相邻的行不算重复值. 语法格式 Usage: uniq ...

  7. 通过JDBC取Oracle数据库的时间字段时,时间丢失,只剩日期

    通过JDBC连接Oracle数据库,在查询的时候发现时间字段取出来值后只剩下了日期,时间消失了.查资料发现跟Oracle jdbc驱动版本有关,这里先贴出解决方案: 修改数据库的连接方式: try { ...

  8. vue 手机键盘把底部按钮顶上去

    背景:在写提交订单页面时候,底部按钮当我点击输入留言信息的时候,底部提交订单按钮被输入法软键盘顶上去遮挡住了. h5 ios输入框与键盘 兼容性优化 实现原理:当页面高度发生变化的时候改变底部butt ...

  9. 使用pm2启动nodejs+express+mysql管理系统步骤

    背景: 由于个人兴趣,了解了一下nodejs+express+mysql项目.在项目搭建完成并开发完成并部署时,遇到一个尴尬的问题,就是后台的servive服务启动问题.日常开发时,打开2个cm窗口, ...

  10. 什么是hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升

    问题1:HashM安排的初始长度,为什么? 初始长度是 16,每次扩展或者是手动初始化,长度必须是 2的幂. 因为: index = HashCode(Key) & (length - 1), ...