# 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. 校验接口:检查是否存在文件,是否存在已上传的部分分片,若存在则返回已上传的分片信息。

# 后端实现:
**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
```