實現大文件斷點續傳(支持網絡異常,服務宕機)
精簡博客內容,儘量已行業術語來分享。
努力做到對每一位認可自己的讀者負責。
幫助別人的同時更是豐富自己的良機。
springboot
mysql
jdk1.8
工作原理
1、前端以分片的形式計算出整個文件的 md5 值以及文件大小 size;
2、使用 md5、 size 去請求後臺判斷文件是否已經存在;
- 有數據,且數據大小與 size 一致,則文件已存在,此時直接結束提示文件已上傳
- 有數據,且數據大小與 size 不一致,則文件上傳了一部分
- 查詢無數據,則未上傳過此文件。此時向數據庫中記錄 name、md5
3、前端遍歷分片進行上傳。判斷分片是否已經上傳,若已上傳則跳過,否則上傳分片文件;
4、若上傳失敗,則保存失敗的文件分片索引;
5、文件分片上傳全部結束,通知服務器進行合併;
6、合併分片結束,並刪除保存的分片臨時文件以及數據庫分片數據
表結構
DROP TABLE IF EXISTS `file`;
CREATE TABLE `file` (
`id` int(11) PRIMARY KEY AUTO_INCREMENT,
`patch_index` int(11) NULL DEFAULT NULL,
`parent` int(11) NULL DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`md5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`size` bigint(11) NOT NULL,
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1179 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
application.yml 參數配置
spring:
datasource:
username: root
password: XXXXXX
url: jdbc:mysql://localhost:3306/springboot?useSSL=false
driver-class-name: com.mysql.jdbc.Driver
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: com.sun.myuploader.model
server:
port: 8080
前端視圖操作
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>文件上傳</title>
<meta charset="UTF-8"/>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/spark-md5.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/patchUpload.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/upload/webuploader/jquery-1.7.2.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/upload/webuploader/webuploader.min.js"></script>
<link href="<%=request.getContextPath()%>/upload/webuploader/webuploader.css" type="css/text" />
<script type="text/javascript" src="<%=request.getContextPath()%>/upload/admin/bootstrap/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>upload/admin/bootstrap/jquery-ui.js"></script>
<link href="<%=request.getContextPath()%>/upload/admin/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
<script type="text/javascript" src="<%=request.getContextPath()%>/upload/admin/bootstrap/bootstrap.min.js"></script>
</head>
<body>
<div style="margin: 30px;">
<h2>文件上傳</h2>
<div style="margin: 20px 20px 20px 0;">
<div id="picker" class="form-control-focus"></div>
<input id="file" type="file"/>
</div>
<div id="thelist" class="uploader-list"></div>
<button id="upload" type="button" class="btn btn-warning">開始同步</button>
</div>
</body>
</html>
效果圖
項目層級目錄結構
項目共享地址
GITHUB:完整Demo鏈接