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

新开神途手游发布网站网络营销的四个特点

新开神途手游发布网站,网络营销的四个特点,广州乐地网站建设,做网站工资待遇前言 在开发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/wzjs/252844.html

相关文章:

  • anaconda可以做网站吗网络营销策划书的结构是什么
  • 做网站二级域名随便用吗aso安卓优化公司
  • 哪些网站可以做简历seo网络推广经理招聘
  • 网站建设方案是什么意思怎么制作网站?
  • 做网站更赚钱吗建设网站推广
  • 梅州建站联系方式如何创建自己的小程序
  • 邵东网站建设成人大专
  • 淮北公司做网站互联网营销顾问
  • 陕西做网站公司有哪些网络宣传
  • cms代码做网站视频广告联盟平台
  • 网站建设思路方案建立网站的详细步骤
  • wordpress网站如何引流郑州做网络优化的公司
  • 电子商务网站建设的简要任务执行书小红书信息流广告
  • 郑州营销网站公司地址app推广有哪些渠道
  • 企业vi设计需求企业seo网络推广
  • 西安app开发公司排名seo优化推广工程师
  • 杨浦手机网站建设友情链接
  • 做效果图去哪个网站接活关键词挖掘网站
  • 深圳国内设计网站app投放推广
  • h5网站开发框架百度 营销怎么收费
  • 嘉兴网站建设托管网站seo分析工具
  • html+css网站模板免费网络推广软件有哪些
  • 网站开发如何处理兼容性问题在线网站流量查询
  • 网易免费企业邮箱登录入口杭州新站整站seo
  • 淘客网站是怎么做的互联网推广方案
  • 昆山高端网站建设机构江门百度seo公司
  • 东莞微信网站建设怎样免费的域名和网站
  • 建旅游网站多少钱网址查询ip地址
  • 如何自己制作公众号网站优化关键词公司
  • flask做的网站项目怎样做平台推广