浅谈文件断点续传和WebUploader的基本结合
0、写在前面的话
1、断点续传的两种方式
1.1 RandomAccessFile
- long getFilePoint():返回文件记录指针的当前位置,不指定指针的位置默认是0
- void seek(long pos):设置文件指针偏移,即将文件记录指针定位到pos位置
1.2 分片处理
2、WebUploader的分片断点续传
var uploader = WebUploader.Uploader({
swf: 'path_of_swf/Uploader.swf',
// 开起分片上传
chunked: true,
// 分片大小,默认5M
chunkSize: 5242880,
// 分片出错后(如网络原因等造成出错)的重传次数
chunkRetry: 2,
// 上传并发数
threads: 1
});
var uploader = WebUploader.Uploader({
swf: 'path_of_swf/Uploader.swf',
// 开起分片上传
chunked: true,
// 分片大小,默认5M
chunkSize: 5242880,
// 分片出错后(如网络原因等造成出错)的重传次数
chunkRetry: 2,
// 上传并发数
threads: 1
});
webUploader.on('uploadBeforeSend', function(block, data){
data.fileMd5 = block.file.wholeMd5;
var deferred = WebUploader.Deferred();
var chunk = data.chunk;
var existChunks = block.file.existChunks;
//后端返回了已存在分片的数组,这里判断要发送的分片是否已存在
if(existChunks && existChunks.indexOf(chunk) != -1) {
//console.log("分片存在,已跳过:" + chunk);
deferred.reject();
} else {
deferred.resolve();
}
return deferred.promise();
});
webUploader.on('uploadBeforeSend', function(block, data){
data.fileMd5 = block.file.wholeMd5;
var deferred = WebUploader.Deferred();
var chunk = data.chunk;
var existChunks = block.file.existChunks;
//后端返回了已存在分片的数组,这里判断要发送的分片是否已存在
if(existChunks && existChunks.indexOf(chunk) != -1) {
//console.log("分片存在,已跳过:" + chunk);
deferred.reject();
} else {
deferred.resolve();
}
return deferred.promise();
});
public boolean uploadChunk() throws ChunkUploadException {
HttpServletRequest request = ServletActionContext.getRequest();
//封装源文件信息
FileInfo srcFileInfo = VideoUtil.getUploadFileInfoByStruts(request, "file");
//获取同时上传的文件其他属性
Map<String, String> params = getVideoParams(request);
if (params.get("fileMd5") == null || "".equals(params.get("fileMd5"))) {
throw new ChunkUploadException("文件md5值未传递");
}
//存放
File temp = new File(getTempPath(params.get("fileMd5")) + "/" + srcFileInfo.getCurChunk());
if (!temp.exists()) {
try {
VideoUtil.copy(srcFileInfo.getFile(), temp);
} catch (IOException e) {
throw new ChunkUploadException("分片上传失败: chunkNum" + params.get("chunk"));
}
}
//如果是最后分片
return !srcFileInfo.isChunked() || srcFileInfo.getCurChunk() == srcFileInfo.getChunkSize() - 1;
}
x
public boolean uploadChunk() throws ChunkUploadException {
HttpServletRequest request = ServletActionContext.getRequest();
//封装源文件信息
FileInfo srcFileInfo = VideoUtil.getUploadFileInfoByStruts(request, "file");
//获取同时上传的文件其他属性
Map<String, String> params = getVideoParams(request);
if (params.get("fileMd5") == null || "".equals(params.get("fileMd5"))) {
throw new ChunkUploadException("文件md5值未传递");
}
//存放
File temp = new File(getTempPath(params.get("fileMd5")) + "/" + srcFileInfo.getCurChunk());
if (!temp.exists()) {
try {
VideoUtil.copy(srcFileInfo.getFile(), temp);
} catch (IOException e) {
throw new ChunkUploadException("分片上传失败: chunkNum" + params.get("chunk"));
}
}
//如果是最后分片
return !srcFileInfo.isChunked() || srcFileInfo.getCurChunk() == srcFileInfo.getChunkSize() - 1;
}
public String upload() {
boolean isLastChunk = false;
try {
isLastChunk = uploadChunk();
} catch (ChunkUploadException e) {
e.printStackTrace();
AjaxSupport.sendFailText(null, e.getMessage());
return AJAX_RESULT;
}
//不是最后的分片,直接返回成功响应
if (!isLastChunk) {
AjaxSupport.sendSuccessText("chunk uploaded", "success");
return AJAX_RESULT;
}
//最后切片
else {
HttpServletRequest request = ServletActionContext.getRequest();
//封装源文件信息
FileInfo srcFileInfo = VideoUtil.getUploadFileInfoByStruts(request, "file");
//获取同时上传的文件其他属性
Map<String, String> params = getVideoParams(request);
//获取合并文件的文件名
String filename = UUID.randomUUID().toString() + "." + srcFileInfo.getFileType();
//合并文件
File tempDir = new File(getTempPath(params.get("fileMd5")));
File[] tempfileArr = tempDir.listFiles();
File storeFile = new File(getStorePath() + "/" + filename);
try {
VideoUtil.merge(tempfileArr, storeFile);
}
...
x
public String upload() {
boolean isLastChunk = false;
try {
isLastChunk = uploadChunk();
} catch (ChunkUploadException e) {
e.printStackTrace();
AjaxSupport.sendFailText(null, e.getMessage());
return AJAX_RESULT;
}
//不是最后的分片,直接返回成功响应
if (!isLastChunk) {
AjaxSupport.sendSuccessText("chunk uploaded", "success");
return AJAX_RESULT;
}
//最后切片
else {
HttpServletRequest request = ServletActionContext.getRequest();
//封装源文件信息
FileInfo srcFileInfo = VideoUtil.getUploadFileInfoByStruts(request, "file");
//获取同时上传的文件其他属性
Map<String, String> params = getVideoParams(request);
//获取合并文件的文件名
String filename = UUID.randomUUID().toString() + "." + srcFileInfo.getFileType();
//合并文件
File tempDir = new File(getTempPath(params.get("fileMd5")));
File[] tempfileArr = tempDir.listFiles();
File storeFile = new File(getStorePath() + "/" + filename);
try {
VideoUtil.merge(tempfileArr, storeFile);
}
...
3、参考链接
浅谈文件断点续传和WebUploader的基本结合的更多相关文章
- SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)
本次的项目环境为 SpringBoot 2.0.4, JDK8.0. 服务器环境为CentOS7.0, Nginx的忘了版本. 前言 SpringBoot使用MultiPartFile接收来自表单的f ...
- 浅谈 举家搬迁静态文件到CDN
由于七牛CDN最近做活动,对于标准用户可以免费使用如下优惠 10 GB 存储空间 10 G/月 下载流量 10 万次/月 PUT/DELETE 请求 100 万次/月 GET 请求 以上这些指标直接就 ...
- 浅谈qmake之pro、pri、prf、prl文件
浅谈qmake之pro.pri.prf.prl文件 转载自:http://blog.csdn.net/dbzhang800/article/details/6348432 尽管每次和cmake对比起来 ...
- 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
浅谈JS中的!=.== .!==.===的用法和区别 var num = 1; var str = '1'; var test = 1; test == num //tr ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 浅谈Linux下/etc/passwd文件
浅谈Linux 下/etc/passwd文件 看过了很多渗透测试的文章,发现在很多文章中都会有/etc/passwd这个文件,那么,这个文件中到底有些什么内容呢?下面我们来详细的介绍一下. 在Linu ...
- 浅谈头文件(.h)和源文件(.cpp)的区别
浅谈头文件(.h)和源文件(.cpp)的区别 本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮.经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能.分门别类展开的文件构成的.一锅 ...
- Android性能优化的浅谈
一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...
- HTTP浅谈
HTTP浅谈 1···什么是HTTP? HTTP协议就是超文本传输协议(HyperText Transfer Protocol),通俗理解是浏览器和web服务器传输数据格式的协议,HTTP协议是一个应 ...
随机推荐
- 如何用ABP框架快速完成项目(13) - 用ABP遇到难题项目受阻时如何避免项目延迟
只有一个人在开发ABP, 遇到难题时可以: 最根本的, 简化问题, 不要盖楼式结构 前端优先用VSCode看文档, 后端看官网文档. 看ABP源码/issues 到QQ群和微信群里寻求外援. 我建 ...
- mybatis的三种批量插入以及次效率比较
1.表结构 CREATE TABLE `t_user` ( `id` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '主键', `name` varc ...
- Android为TV端助力 转载自jguangyou的博客,XML基本属性大全
android:layout_width 指定组件布局宽度 android:layout_height 指定组件布局高度 android:alpha 设置组件透明度 android:backgroun ...
- Android内存优化(四)LeakCanary使用详解
LeakCanary是检测App内存泄露的工具, 内存泄露是Android开发中常见的问题, 使用程序的稳定性下降. LeakCanary 的机制如下: RefWatcher.watch() 会以监控 ...
- springboot 学习之路 6(集成durid连接池)
目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...
- selenium的基本用法
selenium需要配合一个driver 我使用的是chrome的driver 注意一定要下载对应浏览器版本的driver 否则会报错的 http://chromedriver.storage.go ...
- ORACLE如何找到引起账号锁定的IP的一点思考与总结
在ORACLE数据库中,如果没有修改过FAILED_LOGIN_ATTEMPTS的话,默认10次尝试失败后就会锁住用户.此时再登录数据库,就会遇到ORA-28000: the account is l ...
- mssql sqlserver for xml EXPLICIT 用法详解说明
摘要:下文通过举例的方式,详细说明"for xml EXPLICIT"关键字的用法,如下所示:实验环境:sql server 2008 R2 EXPLICIT的功能:将数据表采用特 ...
- mssql sqlserver 获取指定汉字的笔画数的方法分享
转自:http://www.maomao365.com/?p=6421 摘要: 下文讲述计算汉字笔画数的sql函数分享,如下所示: 例:建立汉字笔画数sql函数 )) returns int as b ...
- NVM 安装 nodejs
Windows 安装: 下载NVM 安装包:https://github.com/coreybutler/nvm-windows/releases 下载nvm-setup.zip文件后,解压后安装 安 ...