最近在做视频上传展示的相关业务!但是因为最开始使用的是单文件上传所以一旦遇到大文件上传的速度就非常慢!为此在网上一直找寻分片的方法!得到了思路!

直接讲一下我这边看了那么多文档加上自己理解写的demo(虽然前端大部分代码是网上的)!

在看demo之前需要理解这个分片的思路。

1、假设现在有一个很大的石头搬到某个地方你直接搬的话那么就是走的非常慢还有可能因为外部因素搬到一般摔了那就做了无用功了。

那么现在把石头切割成多个小块你搬小部分石头是不是就很快,然后当全部小石头搬完后在目的地把这些小石头拼接起来是不是还是原来的样

子(别抬杠)。

2、那么分片的原理就是这样文件太大切割成多个小文件在后台接收这些分片然后创建临时文件。在所有分片传完之后调用后台合并接口,将

刚才的分片合并成完整的文件。

直接上前端代码:

JS分片上传-极速上传

$("#slice").change(function(event) {

var file = $("#slice")[0].files[0];

PostFile(file,0);

});

//执行分片上传

function PostFile(file,i, uuid){

var name = file.name, //文件名

size = file.size, //总大小shardSize = 2 * 1024 * 1024,

shardSize = 10 * 1024 * 1024, //以2MB为一个分片,每个分片的大小

shardCount = Math.ceil(size / shardSize); //总片数

if(i >= shardCount){

return;

}

//判断uuid是否存在

if (uuid == undefined || uuid == null) {

uuid = guid();

}

//console.log(size,i+1,shardSize); //文件总大小,第一次,分片大小//

var start = i * shardSize;

var end = start + shardSize;

var packet = file.slice(start, end); //将文件进行切片

/* 构建form表单进行提交 */

var form = new FormData();

form.append("uuid", uuid);// 前端生成uuid作为标识符传个后台每个文件都是一个uuid防止文件串了

form.append("data", packet); //slice方法用于切出文件的一部分

form.append("name", name);

form.append("totalSize", size);

form.append("total", shardCount); //总片数

form.append("index", i + 1); //当前是第几片

$.ajax({

url: "http://127.0.0.1:8080/index/doPost",

type: "POST",

data: form,

//timeout:"10000", //超时10秒

async: true, //异步

dataType:"json",

processData: false, //很重要,告诉jquery不要对form进行处理

contentType: false, //很重要,指定为false才能形成正确的Content-Type

success: function (msg) {

console.log(msg);

/* 表示上一块文件上传成功,继续下一次 */

if (msg.status == 201) {

form = '';

i++;

PostFile(file, i, uuid);

} else if (msg.status == 502) {

form = '';

/* 失败后,每2秒继续传一次分片文件 */

setInterval(function () { PostFile(file, i, uuid) }, 2000);

} else if (msg.status == 200) {

merge(uuid, name)

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

} else if (msg.status == 500) {

console.log('第'+msg.i+'次,上传文件有误!');

} else {

console.log('未知错误');

}

}

})

}

function merge(uuid, fileName) {

$.ajax({

url: "http://127.0.0.1:8080/index/merge",

type: "GET",

data: {uuid: uuid, newFileName: fileName},

//timeout:"10000", //超时10秒

async: true, //异步

dataType:"json",

success: function (msg) {

console.log(msg);

}

})

}

function guid() {

return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {

var r = Math.random() * 16 | 0,

v = c == 'x' ? r : (r & 0x3 | 0x8);

return v.toString(16);

});

}

后台代码:

private static String fileUploadTempDir = "D:/portalupload/fileuploaddir";

private static String fileUploadDir = "D:/portalupload/file";

@RequestMapping("/doPost")

@ResponseBody

public Map fragmentation(HttpServletRequest req, HttpServletResponse resp) {

resp.addHeader("Access-Control-Allow-Origin", "*");

Map map = new HashMap<>();

MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;

// 获得文件分片数据

MultipartFile file = multipartRequest.getFile("data");

// 分片第几片

int index = Integer.parseInt(multipartRequest.getParameter("index"));

// 总片数

int total = Integer.parseInt(multipartRequest.getParameter("total"));

// 获取文件名

String fileName = multipartRequest.getParameter("name");

String name = fileName.substring(0, fileName.lastIndexOf("."));

String fileEnd = fileName.substring(fileName.lastIndexOf("."));

// 前端uuid,作为标识

String uuid = multipartRequest.getParameter("uuid");

File uploadFile = new File(fileUploadTempDir + "/" + uuid, uuid + name + index + ".tem");

if (!uploadFile.getParentFile().exists()) {

uploadFile.getParentFile().mkdirs();

}

if (index < total) {

try {

file.transferTo(uploadFile);

// 上传的文件分片名称

map.put("status", 201);

return map;

} catch (IOException e) {

e.printStackTrace();

map.put("status", 502);

return map;

}

} else {

try {

file.transferTo(uploadFile);

// 上传的文件分片名称

map.put("status", 200);

return map;

} catch (IOException e) {

e.printStackTrace();

map.put("status", 502);

return map;

}

}

}

@RequestMapping(value = "/merge", method = RequestMethod.GET)

@ResponseBody

public Map merge(String uuid, String newFileName) {

Map retMap = new HashMap();

try {

File dirFile = new File(fileUploadTempDir + "/" + uuid);

if (!dirFile.exists()) {

throw new RuntimeException("文件不存在!");

}

//分片上传的文件已经位于同一个文件夹下,方便寻找和遍历(当文件数大于十的时候记得排序用冒泡排序确保顺序是正确的)

String[] fileNames = dirFile.list();

// 创建空的合并文件

File targetFile = new File(fileUploadDir, newFileName);

RandomAccessFile writeFile = new RandomAccessFile(targetFile, "rw");

int position = 0;

for (String fileName : fileNames) {

System.out.println(fileName);

File sourceFile = new File(fileUploadTempDir + "/" + uuid, fileName);

RandomAccessFile readFile = new RandomAccessFile(sourceFile, "rw");

int chunksize = 1024 * 3;

byte[] buf = new byte[chunksize];

writeFile.seek(position);

int byteCount = 0;

while ((byteCount = readFile.read(buf)) != -1) {

if (byteCount != chunksize) {

byte[] tempBytes = new byte[byteCount];

System.arraycopy(buf, 0, tempBytes, 0, byteCount);

buf = tempBytes;

}

writeFile.write(buf);

position = position + byteCount;

}

readFile.close();

FileUtils.deleteQuietly(sourceFile);//删除缓存的临时文件

}

writeFile.close();

retMap.put("code", "200");

}catch (IOException e){

e.printStackTrace();

retMap.put("code", "500");

}

return retMap;

}

大概就是这样的思路。

如有更好的方法请告诉小弟,小弟也在学习中。

java 大文件上传_JAVA大文件上传分片上传方法(附带demo)相关推荐

  1. java 断点上传_java HTTP文件断点上传

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  2. ssm上传文件进度条_Java 单文件、多文件上传 / 实现上传进度条

    日常,工作 在这里总结一下上传吧(是以前做过的练习,就汇总到个人博客吧) java ssm 框架实现文件上传 实现:单文件上传.多文件上传(单选和多选),并且用 ajax 异步刷新,在当前界面显示上传 ...

  3. java图片和视频上传_Java实现视频网站的视频上传、视频转码、视频关键帧抽图, 及视频播放功能(转)...

    视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpe ...

  4. java通知图库更新视频_Java实现视频网站的视频上传、视频转码、视频关键帧抽图, 及视频播放功能...

    视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpe ...

  5. java压缩zip文件夹错误_Java将文件或者文件夹压缩成zip(修复文件夹中存在多个文件报Stream Closed错误问题)...

    项目场景: Java将文件或者文件夹压缩成zip(修复文件夹中存在多个文件报Stream Closed错误问题) 问题描述: 最近的项目需要将多级文件夹压缩成zip,网上找了几个工具类,都会报错,所以 ...

  6. java 文件随机读取_Java 实现文件随机读写-RandomAccessFile

    现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下"Lucene是一款非常优秀的全文检索库".可能大多数朋友会觉得这个需求很easy,说实话,确实easy ...

  7. java文件是什么_java类文件是什么?

    一.什么是Java类文件    Java类文件是Java程序的二进制表示形式.每一个类文件代表一个类或者接口.不可能在一个类文件中放入多个类或者接口.这样就使得无论类文件是在哪一种平台上生成,都可以在 ...

  8. java遍历文件和归类_java读取文件的两种方法:java.io和java.lang.ClassLoader

    java读取文件的两种方法:java.io和java.lang.ClassLoader 什么时候使用java.io,什么时候使用java.lang.ClassLoader呢? (注:要是之前读xml文 ...

  9. java创建文件夹代码_Java创建文件夹及文件实例代码

    package com.xhkj.util; import java.io.File; import java.io.IOException; public class CreateFileUtil ...

最新文章

  1. perl 中单引号双引号的区别-----perl学习笔记
  2. .net你不行——是你的父亲把你封装的太死,还是你的子孙们太懒,未把你发扬光大。...
  3. java 鼠标单击_不通过鼠标点击,单纯的通过Java代码生成鼠标单击事件
  4. mysql readline_readLine的两种用法
  5. java内存泄漏和内存溢出_Java和内存泄漏
  6. 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上) #华为云·寻找黑马程序员#
  7. mysql5.7.12无法启动_MySql5.7.12免安装版配置以及服务无法启动问题解决方法
  8. 数论基础——素数判断约数枚举整数分解(模板)
  9. Cannot resolve plugin org.apache.maven.plugins:xxxx
  10. php 在线api文档生成,一键生成API文档
  11. 2.3、IPMP,PMP,PRINCE2
  12. 51nod 1299 监狱逃离
  13. dota2自走棋Android怎么更新,dota2自走棋
  14. java-net-php-python-ssm仿猫眼电影计算机毕业设计程序
  15. C++ Learn from菜鸟教程
  16. 会声会影2023最新中文旗舰版新功能介绍
  17. HTML给SELECT标签赋值
  18. (AAAI-2019)用于行人重识别的水平金字塔匹配
  19. InteractiveDataDisplay.WPF 固定坐标轴
  20. 74HC595使用说明与驱动原理

热门文章

  1. 解决pycharm 提示no tests were found的问题
  2. 如何在熊猫数据框的列中将所有NaN值替换为零
  3. 使用Json.net进行序列化时,如何更改属性名称?
  4. win11触屏模式在哪 Windows11触屏模式的设置方法
  5. 更改项目project名称,与项目名称;
  6. CentOS[linux]操作系统的安装手册
  7. C语言之数据类型,C语言之数据类型
  8. vue点击网页全屏_vue中实现点击变成全屏的多种方法
  9. 技能类别mysql_MySQL 数据类型
  10. python的方向_Python Shell下方向键显示「^[[C^[[D」修复方法