# uploader **Repository Path**: J_M_Hao/uploader ## Basic Information - **Project Name**: uploader - **Description**: 文件上传 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-12-05 - **Last Updated**: 2023-12-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 文件上传优化 文件上传时会存在的一些问题:比较慢;中途退出或者网络延迟,容易出现超时、上传失败等问题。这种问题尤其在大文件上传时会经常出现,所以一般会选择分片上传、断点续传、秒传来实现。 分片上传:分片上传是将大文件分割成多个小块(分片),然后逐个上传这些小块。小块可以并行上传,从而提高上传速度。一旦所有分片上传完成,服务器可以将这些分片合并成完整的文件。 断点续传:断点续传是一种允许在上传中断后可以从中断处继续进行,而不需要重新上传整个文件。 秒传:秒传实际上就是不上传。允许用户在上传文件时,如果服务器已经存在完全相同的文件,就直接跳过上传过程,实现瞬间完成的效果。 # 实现思路 前端:Vue3 + antdv + spark-md5 + [Web Worker] 1. 用户在前端选择文件,使用 spark-md5 进行文件分片并计算文件 hash 值。 2. 将分片上传至后端,上传前校验文件是否已存在,如果存在则上传缺失的分片。 3. 完成分片上传后,向服务器发出合并请求,等待合并结果。 4. 收到合并完成的消息和文件访问路径,显示给用户。 > Web Worker用于优化优化效率 服务端:SpringBoot + JPA + MySQL 服务端需要提供三个接口:接收文件分片、合并分片、校验文件状态。 1. 接收文件分片接口:将上传的文件分片按文件名创建文件夹,每个分片作为文件保存。 2. 合并分片接口:接收文件名,查找对应文件夹下的分片,排序后读取文件流,生成完整文件并返回文件访问路径。 3. 校验接口:检查是否存在文件,是否存在已上传的部分分片,若存在则返回已上传的分片信息。 ![](upload.png) # 后端实现: **init.sql** ```sql DROP DATABASE IF EXISTS upload; CREATE DATABASE upload; DROP TABLE IF EXISTS `upload`.`chunk`; CREATE TABLE `upload`.`chunk` ( `id` int NOT NULL primary key AUTO_INCREMENT comment '主键', `chunk_index` int(11) NOT NULL comment '分片序号', `chunk_size` bigint(20) NOT NULL comment '分片大小', `current_chunk_size` bigint(20) NOT NULL comment '当前分片大小', `filename` varchar(255) NOT NULL comment '文件名', `identifier` varchar(255) NOT NULL comment '文件标识', `relative_path` varchar(255) NOT NULL comment '文件相对路径', `total_chunks` int(11) NOT NULL comment '总分片数', `total_size` bigint(20) NOT NULL comment '总大小', ) ; DROP TABLE IF EXISTS `upload`.`file_info`; CREATE TABLE `upload`.`file_info` ( `id` int NOT NULL primary key AUTO_INCREMENT comment '主键', `filename` varchar(255) NOT NULL comment '文件名', `identifier` varchar(255) NOT NULL comment '文件标识', `location` varchar(255) NOT NULL comment '文件存储位置', `total_size` bigint(20) NOT NULL comment '总大小', `type` varchar(255) NOT NULL comment '文件类型' ) ``` ## 创建Springboot工程 **pom.xml**: ```xml org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-web com.mysql mysql-connector-j runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test ``` # 前端实现: 创建 Vue 工程后,安装需要的库 ```js // antdv npm i --save ant-design-vue // icons npm install --save @ant-design/icons-vue // vue-router npm i vue-router@4 --save // axios.js npm i axios --save // spark-md5 npm i spark-md5 --save ```