当前位置: 首页 > news >正文

免费网站新域名建设工程申报系统网站

免费网站新域名,建设工程申报系统网站,网站如何做图片自动切换,服务周到的上海网站建设公前言 在开发Web应用时,文件上传是一个常见需求。然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余。此时可以使用文件秒传技术通过识别重复文件,实现瞬间完成上传的效果,大大提升了用户体验…

前言

在开发Web应用时,文件上传是一个常见需求。然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余。此时可以使用文件秒传技术通过识别重复文件,实现瞬间完成上传的效果,大大提升了用户体验和系统效率。

文件秒传原理

文件秒传的核心原理是:

  1. 计算文件唯一标识(通常是MD5或SHA256值)
  2. 上传前先检查服务器是否已存在相同标识的文件
  3. 若存在,则直接引用已有文件,无需再次上传
  4. 若不存在,则执行常规上传流程

这种方式能显著减少网络传输避免存储冗余

代码实现

1. 创建项目基础结构

首先创建Spring Boot项目,添加必要依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.1</version></dependency>
</dependencies>

2. 创建上传存储代码

此处使用一个简单的集合来存储文件信息,实际使用需要替换为数据库或其他持久化中间件。

import cn.hutool.crypto.digest.DigestUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Service
public class FileService {// 使用Map存储文件信息,key为MD5,value为文件信息(实际使用时可替换为数据库存储)private final Map<String, FileInfo> fileStore = new ConcurrentHashMap<>();/*** 检查文件是否已存在*/public FileInfo findByMd5(String md5) {return fileStore.get(md5);}/*** 保存文件信息*/public FileInfo saveFile(String fileName, String fileMd5, Long fileSize, String filePath) {FileInfo fileInfo = new FileInfo(fileName, fileMd5, fileSize, filePath);fileStore.put(fileMd5, fileInfo); // 实际使用时插入数据库return fileInfo;}/*** 计算文件MD5*/public String calculateMD5(MultipartFile file) throws IOException {return DigestUtil.md5Hex(file.getInputStream());}
}

定义一个简单的文件信息实体类:

import cn.hutool.core.util.IdUtil;public class FileInfo {private String id = IdUtil.fastUUID();private String fileName;private String fileMd5;private Long fileSize;private String filePath;public FileInfo(String fileName, String fileMd5, Long fileSize, String filePath) {this.fileName = fileName;this.fileMd5 = fileMd5;this.fileSize = fileSize;this.filePath = filePath;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public String getFileMd5() {return fileMd5;}public void setFileMd5(String fileMd5) {this.fileMd5 = fileMd5;}public Long getFileSize() {return fileSize;}public void setFileSize(Long fileSize) {this.fileSize = fileSize;}public String getFilePath() {return filePath;}public void setFilePath(String filePath) {this.filePath = filePath;}
}

3. 创建Result类

为了统一返回结果格式,可以创建一个简单的Result类。

public class Result {private boolean success;private Object data;private String message;public Result(boolean success, Object data, String message) {this.success = success;this.data = data;this.message = message;}public static Result success(Object data) {return new Result(true, data,"success");}public static Result success(Object data,String message) {return new Result(true, data,message);}public static Result error(String message) {return new Result(false, null, message);}// Getterspublic boolean isSuccess() { return success; }public Object getData() { return data; }public String getMessage() { return message; }
}

4. 创建Controller控制器

import cn.hutool.core.io.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.File;@RestController
@RequestMapping("/api/file")
public class FileController {private static Logger logger = LoggerFactory.getLogger(FileController.class);@Autowiredprivate FileService fileService;/*** 检查文件是否已存在*/@PostMapping("/check")public Result checkFile(@RequestParam("md5") String md5) {FileInfo fileInfo = fileService.findByMd5(md5);if (fileInfo != null) {return Result.success(fileInfo);}return Result.success(null);}/*** 上传文件*/@PostMapping("/upload")public Result uploadFile(@RequestParam("file") MultipartFile file) {try {// 计算文件MD5值String md5 = fileService.calculateMD5(file);// 检查文件是否已存在FileInfo existFile = fileService.findByMd5(md5);if (existFile != null) {// todo 进行自定义的逻辑处理return Result.success(existFile,"文件秒传成功");}// 文件不存在,执行上传String originalFilename = file.getOriginalFilename();String filePath = FileUtil.getTmpDir() + File.separator + originalFilename; // 保存到临时目录// 存储文件file.transferTo(new File(filePath));// 保存文件信息到内存(实际使用时应替换为数据库)FileInfo fileInfo = fileService.saveFile(originalFilename, md5, file.getSize(), filePath);return Result.success(fileInfo,"文件上传成功");} catch (Exception e) {logger.error(e.getMessage(),e);return Result.error("文件上传失败:" + e.getMessage());}}
}

4. 创建纯HTML前端页面

创建一个简单的HTML上传页面:

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>文件秒传示例</title><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script src="https://cdn.jsdelivr.net/npm/spark-md5@3.0.2/spark-md5.min.js"></script>
</head>
<body><h2>文件上传(支持秒传)</h2><input type="file" id="fileInput" /><button onclick="uploadFile()">上传文件</button><div id="progressBar" style="display:none;"><div>上传进度:<span id="progress">0%</span></div></div><div id="result"></div><script>function uploadFile() {const fileInput = document.getElementById('fileInput');const file = fileInput.files[0];if (!file) {alert('请选择文件');return;}document.getElementById('progressBar').style.display = 'block';document.getElementById('result').innerText = '计算文件MD5中...';// 计算文件MD5calculateMD5(file).then(md5 => {document.getElementById('result').innerText = '正在检查文件是否已存在...';// 检查文件是否已存在return axios.post('/api/file/check', {md5: md5}).then(response => {if (response.data.data && response.data.data.id) {// 文件已存在,执行秒传document.getElementById('result').innerText = '文件秒传成功!';document.getElementById('progress').innerText = '100%';return Promise.resolve();} else {// 文件不存在,执行上传const formData = new FormData();formData.append('file', file);return axios.post('/api/file/upload', formData, {onUploadProgress: progressEvent => {const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);document.getElementById('progress').innerText = percentCompleted + '%';}}).then(response => {document.getElementById('result').innerText = '文件上传成功!';});}});}).catch(error => {document.getElementById('result').innerText = '错误:' + error.message;});}// 计算文件MD5function calculateMD5(file) {return new Promise((resolve, reject) => {const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;const chunkSize = 2097152; // 2MBconst chunks = Math.ceil(file.size / chunkSize);let currentChunk = 0;const spark = new SparkMD5.ArrayBuffer();const fileReader = new FileReader();fileReader.onload = function(e) {spark.append(e.target.result);currentChunk++;if (currentChunk < chunks) {loadNext();} else {resolve(spark.end());}};fileReader.onerror = function() {reject('文件读取错误');};function loadNext() {const start = currentChunk * chunkSize;const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));}loadNext();});}</script>
</body>
</html>

5. 配置文件

application.yml中添加必要配置

server:port: 8080spring:servlet:multipart:max-file-size: 100MBmax-request-size: 100MB

效果

第一次上传

在这里插入图片描述

第二次上传

在这里插入图片描述

http://www.dtcms.com/a/576564.html

相关文章:

  • 织梦网站广告html做的好看的网站
  • 网站建设哪家g好移动互联网开发
  • 微信小程序开发收费东莞seo建站公司
  • 设计师接单网站如何做国外的电商网站设计
  • 昆山建设局网站表格下国外模板网站
  • 高端网站建设公司哪家公司好城固网站建设
  • 织梦修改网站标题网络营销软文范例300
  • 创建网站的准备移动互联网开发考试
  • 广东省建设厅网站查询做同城网站最赚钱
  • 湖南建立网站营销策划搜索引擎营销漏斗模型
  • 网页制作工具的选择与网站整体风格大连招聘网最新招聘
  • 网站制作推广方案做外包网站的公司是怎样的
  • 网站 语言选择山西省网站
  • 免费企业网站建设单位wordpress调用当前子分类
  • 如何做阅读网站婚纱摄影网站的设计思路
  • 芜湖公司网站建设wordpress无限地址
  • 冠县网站建设gxsh如何建设一个属于自己的网站
  • 通信网站建设关于建设集团公司网站的报告
  • 江苏省建设工程上岗证查询网站WordPress增加文章来源插件
  • jsp网站建设 书籍有什么网站交互做的很好 知乎
  • 在哪个网站开发外贸业务网站注销主体填写原因
  • 用python写一个简单的网页seo推广公司教程
  • 常州钟楼区邹区建设局网站网站运营怎么样
  • 栾川网站开发微信小程序脚本
  • 网站设计制作策划书韩国做 mp4下载网站
  • 网站建设客户调查需求表wordpress 5.0.2
  • 校园网二手书交易网站建设重庆介绍ppt制作
  • 湛江市建设教育协会学校网站wordpress视频教程百度网盘
  • 网站开发需要服务器吗做3d图的网站有哪些软件
  • 中国建设银行官方网站下载wordpress 自动分页