技术驱动:探索SpringBoot的大文件上传策略

1.分片上传技术

为了处理大文件上传并保证性能,前后端可以使用分片上传(也称为分块上传)技术。

1.选择原因

分片上传(也称为分块上传)是一种处理大文件上传的技术,主要目的是提高上传的可靠性和效率。
网络稳定性和可靠性
断点续传:在上传大文件时,网络中断是一个常见的问题。如果没有分片上传,整个文件上传过程必须重新开始,这样不仅浪费时间,还增加了失败的可能性。而分片上传允许在网络恢复后从中断的地方继续上传,从而提高了上传的可靠性。
错误恢复:上传过程中,如果某个分片上传失败,只需重新上传这个分片,而不需要重新上传整个文件。
资源管理
内存消耗:上传大文件时,如果一次性读取整个文件,会占用大量内存,甚至可能导致内存溢出。而分片上传每次只读取和上传一个小块,内存消耗更可控。
带宽优化:分片上传可以更好地利用带宽资源,特别是在网络不稳定的情况下,分片上传可以避免带宽的浪费。
大文件支持
文件大小限制:一些浏览器和服务器对单个文件的上传大小有限制。通过分片上传,可以绕过这些限制,使上传大文件成为可能。
服务器处理压力:一次性上传大文件会给服务器带来很大的压力,分片上传可以减轻服务器的负担,因为服务器可以逐片处理和存储文件。

2.前端处理

1.文件分片:将大文件分成多个小块,每个块的大小可以根据需求设定。
2.上传分片:逐个上传分片,每个分片上传成功后上传下一个分片。
3.上传进度:可以通过计算已上传分片的大小来展示上传进度。
4.合并分片:所有分片上传完成后,通知后端合并分片。

3.后端处理

1.接收分片:后端接收每个分片并存储。
2.合并分片:在接收到所有分片后,将分片合并成完整文件。
3.处理上传进度和失败重传:记录上传进度,支持失败重传。

2.整合particles.js

particles.js 是一个轻量级的 JavaScript 库,用于在网页上创建交互性和美观的粒子效果。它能够生成各种各样的粒子动画,例如气泡、雪花、星星等,并且可以响应用户的鼠标移动和点击事件,增加网页的动态效果和吸引力。

1.主要特性

  • 轻量级particles.js 体积小,加载速度快。
  • 高效:使用 HTML5 的 canvas 元素进行渲染,性能优越。
  • 高度可定制:提供丰富的配置选项,可以自定义粒子的数量、颜色、形状、大小、速度等。
  • 交互性:支持鼠标事件,例如悬停和点击,从而实现粒子的交互效果。
  • 响应式:能够适应不同屏幕大小,确保在各种设备上的显示效果。

2.安装与使用

1. 引入 particles.js

你可以通过 CDN 或者下载文件的方式引入 particles.js

使用 CDN:

<!-- 使用 CDN 引入 -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>

下载文件:

你可以从 GitHub 下载 particles.js 文件,并将其放置在项目中,然后使用以下方式引用:

<script src="path/to/particles.min.js"></script>
2. 创建粒子容器

在 HTML 中创建一个容器,用于显示粒子效果:

<div id="particles-js"></div>
3. 初始化 particles.js

在 JavaScript 中初始化 particles.js 并进行配置:

<script>
particlesJS('particles-js', {
                "particles": {
                    "number": {
                        "value": 80,//粒子数量
                        "density": {
                            "enable": true,
                            "value_area": 800 //粒子活动区域
                        }
                    },
                    "color": {
                        "value": "#333333" //粒子颜色
                    },
                    "shape": {
                        "type": "circle", //粒子形状
                        "stroke": { //粒子的描边
                            "width": 0,
                            "color": "#000000"
                        },
                        "polygon": {
                            "nb_sides": 5
                        }
                    },
                    "opacity": { //粒子透明度
                        "value": 0.5,
                        "random": false,
                        "anim": {
                            "enable": false, //是否开启
                            "speed": 1,//动画速度
                            "opacity_min": 0.1,
                            "sync": false
                        }
                    },
                    "size": {
                        "value": 5,
                        "random": true,
                        "anim": {
                            "enable": false,
                            "speed": 40,
                            "size_min": 0.1,
                            "sync": false
                        }
                    },
                    "line_linked": {//粒子之间的连线配置
                        "enable": true,//是否开启连线
                        "distance": 150,//连线距离
                        "color": "#333333",//连线的颜色
                        "opacity": 0.4,
                        "width": 1 //连线宽度
                    },
                    "move": {
                        "enable": true, //粒子是否移动
                        "speed": 6,//粒子移动速度
                        "direction": "none",//粒子移动方向
                        "random": true,//是否随机移动
                        "straight": false,//是否直线移动
                        "out_mode": "out",
                        "bounce": false,//是否开启碰撞弹跳
                        "attract": {
                            "enable": false,
                            "rotateX": 600,
                            "rotateY": 1200
                        }
                    }
                },
                "interactivity": {
                    "detect_on": "canvas",
                    "events": {
                        "onhover": {//鼠标悬浮效果
                            "enable": true,
                            "mode": "repulse"
                        },
                        "onclick": {//鼠标点击效果
                            "enable": true,
                            "mode": "push"
                        },
                        "resize": true
                    },
                    "modes": {
                        "grab": {
                            "distance": 400,
                            "line_linked": {
                                "opacity": 1
                            }
                        },
                        "bubble": {
                            "distance": 400,
                            "size": 40,
                            "duration": 2,
                            "opacity": 8,
                            "speed": 3
                        },
                        "repulse": {
                            "distance": 200,
                            "duration": 0.4
                        },
                        "push": {
                            "particles_nb": 4
                        },
                        "remove": {
                            "particles_nb": 2
                        }
                    }
                },
                "retina_detect": true //是否启动视网膜屏检测
            });
</script>

3.配置选项

  • number: 粒子的数量及密度。
  • color: 粒子的颜色。
  • shape: 粒子的形状,可以是 circle(圆形)、edge(边缘)、triangle(三角形)、polygon(多边形)或 image(图片)。
  • opacity: 粒子的透明度。
  • size: 粒子的大小。

具体的配置可以在Github中查看,如下所示:
在这里插入图片描述

3.前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload with Particles.js Background</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f9;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
        }

        .container {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            text-align: center;
            z-index: 1;
            position: relative;
        }

        h1 {
            color: #333;
        }

        input[type="file"] {
            margin: 10px 0;
        }

        button {
            background-color: #007bff;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }

        button:hover {
            background-color: #0056b3;
        }

        progress {
            width: 100%;
            height: 20px;
            margin-top: 10px;
            border-radius: 4px;
        }

        #particles-js {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: 0;
        }
    </style>
    <!-- 使用 CDN 引入 -->
    <script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
</head>
<body>
    <div id="particles-js"></div>
    <div class="container">
        <h1>File Upload</h1>
        <input type="file" id="fileInput" />
        <button onclick="uploadFile()">Upload</button>
        <progress id="progressBar" value="0" max="100"></progress>
    </div>

    <script>
        particlesJS('particles-js', {
                "particles": {
                    "number": {
                        "value": 80,//粒子数量
                        "density": {
                            "enable": true,
                            "value_area": 800 //粒子活动区域
                        }
                    },
                    "color": {
                        "value": "#333333" //粒子颜色
                    },
                    "shape": {
                        "type": "circle", //粒子形状
                        "stroke": { //粒子的描边
                            "width": 0,
                            "color": "#000000"
                        },
                        "polygon": {
                            "nb_sides": 5
                        }
                    },
                    "opacity": { //粒子透明度
                        "value": 0.5,
                        "random": false,
                        "anim": {
                            "enable": false, //是否开启
                            "speed": 1,//动画速度
                            "opacity_min": 0.1,
                            "sync": false
                        }
                    },
                    "size": {
                        "value": 5,
                        "random": true,
                        "anim": {
                            "enable": false,
                            "speed": 40,
                            "size_min": 0.1,
                            "sync": false
                        }
                    },
                    "line_linked": {//粒子之间的连线配置
                        "enable": true,//是否开启连线
                        "distance": 150,//连线距离
                        "color": "#333333",//连线的颜色
                        "opacity": 0.4,
                        "width": 1 //连线宽度
                    },
                    "move": {
                        "enable": true, //粒子是否移动
                        "speed": 6,//粒子移动速度
                        "direction": "none",//粒子移动方向
                        "random": true,//是否随机移动
                        "straight": false,//是否直线移动
                        "out_mode": "out",
                        "bounce": false,//是否开启碰撞弹跳
                        "attract": {
                            "enable": false,
                            "rotateX": 600,
                            "rotateY": 1200
                        }
                    }
                },
                "interactivity": {
                    "detect_on": "canvas",
                    "events": {
                        "onhover": {//鼠标悬浮效果
                            "enable": true,
                            "mode": "repulse"
                        },
                        "onclick": {//鼠标点击效果
                            "enable": true,
                            "mode": "push"
                        },
                        "resize": true
                    },
                    "modes": {
                        "grab": {
                            "distance": 400,
                            "line_linked": {
                                "opacity": 1
                            }
                        },
                        "bubble": {
                            "distance": 400,
                            "size": 40,
                            "duration": 2,
                            "opacity": 8,
                            "speed": 3
                        },
                        "repulse": {
                            "distance": 200,
                            "duration": 0.4
                        },
                        "push": {
                            "particles_nb": 4
                        },
                        "remove": {
                            "particles_nb": 2
                        }
                    }
                },
                "retina_detect": true //是否启动视网膜屏检测
            });
        const CHUNK_SIZE = 1024 * 1024; // 1MB per chunk

        async function uploadFile() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];
            const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
            // 将大文件分片上传
            for (let i = 0; i < totalChunks; i++) {
                const start = i * CHUNK_SIZE;
                const end = Math.min(start + CHUNK_SIZE, file.size);
                const chunk = file.slice(start, end);
                const formData = new FormData();
                formData.append('chunkFile', chunk);
                formData.append('index', i);
                await fetch('http://127.0.0.1:8080/upload', {
                    method: 'POST',
                    body: formData
                });
                document.getElementById('progressBar').value = (i + 1) / totalChunks * 100;
            }

            // Notify server to merge chunks
            await fetch('http://127.0.0.1:8080/merge', {
                method: 'POST',
                body: JSON.stringify({ fileName: file.name }),
                headers: { 'Content-Type': 'application/json' }
            });
        }
    </script>
</body>
</html>

对应的界面效果如下所示:

在这里插入图片描述

4.后端代码

1.创建一个SpringBoot项目(模块)

在这里插入图片描述
后面只需要导入Spring Web模块即可!
这里创建项目或者模块后,如果发现maven始终无法下载对应的依赖,那就需要更新maven的镜像仓库配置。
可以找到maven中的conf目录下的setting.xml文件,修改里面的mirror标签的内容,具体如下所示:

<mirror>
    <!--This sends everything else to /public -->
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

在这里插入图片描述

2.文件上传配置

需要在resources下的application.properties写一些配置项,来保证文件的正常上传等功能!具体如下所示:

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

3.控制层代码

这里在类的层级下通过 @CrossOrigin 设置的跨域,也可以通过写配置文件在全局设置跨域!

package com.xing.bigfileuploaddemo.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;

@RestController
@CrossOrigin
public class BigFileUploadController {
    // 获取资源文件夹的路径
    private static final String UPLOAD_DIR = System.getProperty("user.dir") + "/upload/";
    @GetMapping("/hello")
    public String hello(){
        return "hello BigFileUpload";
    }


    @PostMapping("/upload")
    public String uploadChunk(@RequestParam("chunkFile") MultipartFile chunkFile,
                                              @RequestParam("index") int index) {
        File uploadDir = new File(UPLOAD_DIR);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        File file = new File(UPLOAD_DIR + "chunk_" + index);
        try {
            chunkFile.transferTo(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ("Chunk " + index + " uploaded");
    }

    @PostMapping("/merge")
    public String mergeChunks(@RequestBody Map<String, String> request) throws FileNotFoundException {
        String filename = request.get("fileName");
        File mergedFile = new File(UPLOAD_DIR + filename);
        try (FileOutputStream fos = new FileOutputStream(mergedFile)) {
            for(int i=0;;i++){
                File chunkFile = new File(UPLOAD_DIR + "chunk_" + i);
                if(!chunkFile.exists()){
                    break;
                }
                Files.copy(chunkFile.toPath(), fos);
                chunkFile.delete();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return "File merged successfully";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/775518.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用requirements.txt配置环境

1. 在anaconda创建环境 创建Python版本为3.8的环境&#xff0c;与yolov5所需的包适配。 2. 在Anaconda Prompt中激活环境 (base) C:\Users\吴伊晴>conda activate yolov5 3. 配置环境 用指定路径中的requirements.txt配置环境。 (yolov5) C:\Users\吴伊晴>pip insta…

LeetCode热题100刷题4:76. 最小覆盖子串、239. 滑动窗口最大值、53. 最大子数组和、56. 合并区间

76. 最小覆盖子串 滑动窗口解决字串问题。 labuladong的算法小抄中关于滑动窗口的算法总结&#xff1a; class Solution { public:string minWindow(string s, string t) {unordered_map<char,int> need,window;for(char c : t) {need[c];}int left 0, right 0;int …

【手机取证】如何使用360加固助手给apk加固

文章关键词&#xff1a;手机取证、电子数据取证、数据恢复 一、前言 APP加固是对APP代码逻辑的一种保护。原理是将应用文件进行某种形式的转换&#xff0c;包括不限于隐藏&#xff0c;混淆&#xff0c;加密等操作&#xff0c;进一步保护软件的利益不受损坏&#xff0c;下面给…

Java并发编程知识整理笔记

目录 ​1. 什么是线程和进程&#xff1f; 线程与进程有什么区别&#xff1f; 那什么是上下文切换&#xff1f; 进程间怎么通信&#xff1f; 什么是用户线程和守护线程&#xff1f; 2. 并行和并发的区别&#xff1f; 3. 创建线程的几种方式&#xff1f; Runnable接口和C…

pycharm如何使用jupyter

目录 配置jupyter新建jupyter文件别人写的方法&#xff08;在pycharm种安装&#xff0c;在网页中使用&#xff09; pycharm专业版 配置jupyter 在pycharm终端启动一个conda虚拟环境&#xff0c;输入 conda install jupyter会有很多前置包需要安装&#xff1a; 新建jupyter…

中国IDC圈探访北京•光子1号金融算力中心

今天&#xff0c;“AI”、“大模型”是最炙手可热的话题&#xff0c;全球有海量人群在工作生活中使用大模型&#xff0c;大模型产品涉及多模态&#xff0c;应用范围已涵盖电商、传媒、金融、短视频、制造等众多行业。 而回看2003年的互联网记忆&#xff0c; “上网”“在线”是…

空状态页面设计的艺术与科学

空状态界面是用户在网站、APP中遇到的因无数据展示而中断体验的界面&#xff0c;这个界面设计对于解决用户疑惑有着很大的帮助。那么我们应该如何设计空状态界面呢&#xff1f;空状态是指在界面设计中&#xff0c;没有内容或数据时所显示的状态。它可能出现在各种情况下&#x…

可视化大屏的强势在于预警和感知的科学依据可靠性强

**可视化大屏的强势&#xff1a;预警与感知的科学依据可靠性探究** 数据可视化已成为信息传递的重要手段。其中&#xff0c;可视化大屏作为一种直观、高效的展示方式&#xff0c;广泛应用于各个领域&#xff0c;如智慧城市、智慧交通、智慧医疗等。可视化大屏的强势不仅体现在…

【最详细】PhotoScan(MetaShape)全流程教程

愿天下心诚士子&#xff0c;人人会PhotoScan&#xff01; 愿天下惊艳后辈&#xff0c;人人可剑开天门&#xff01; 本教程由CSDN用户CV_X.Wang撰写&#xff0c;所用数据均来自山东科技大学视觉测量研究团队&#xff0c;特此鸣谢&#xff01;盗版必究&#xff01; 一、引子 Ph…

振弦式多点位移计是什么?有什么作用?

在复杂的工程结构监测中&#xff0c;位移、沉降、应变等参数的精确测量对于确保工程安全和质量至关重要。振弦式多点位移计作为一种高精度、高可靠性的测量工具&#xff0c;广泛应用于桥梁、隧道、大坝、高层建筑等各类工程结构的健康监测中。南京峟思将给大家详细介绍振弦式多…

抖音同款网红告白小工具(附源码带下载链接)

抖音同款表白小程序 仿抖音同款表白小程序&#xff0c;在 [Python让你的表白更浪漫&#xff01;&#xff01;] 打包好的可执行文件下载&#xff08;包括win和mac&#xff09;&#xff1a;https://pan.baidu.com/s/1Y9kccxtXrskrA5L7gqCaFg 效果演示&#xff1a; 以下为源代码&a…

TK养号工具开发会用上的源代码科普!

在当今数字化时代&#xff0c;社交媒体平台的崛起使得网络账号的维护与管理变得日益重要&#xff0c;其中&#xff0c;TK作为一款备受欢迎的社交媒体平台&#xff0c;吸引了大量用户。 在TK上进行账号养护&#xff0c;即通过各种方式提升账号权重、增加曝光量&#xff0c;已成…

nginx部署多个项目;vue打包项目部署设置子路径访问;一个根域名(端口)配置多个子项目

本文解决&#xff1a; vue打包项目部署设置子路径访问&#xff1b;nginx部署多个子项目&#xff1b;一个ip/域名 端口 配置多个子项目&#xff1b;配置后&#xff0c;项目能访问&#xff0c;但是刷新页面就丢失的问题 注&#xff1a;本文需要nginx配置基础。基础不牢的可见文…

SEELE框架:图像中主体重定位的创新方法

现有的图像编辑工具多集中于静态调整&#xff0c;如替换图像中的特定区域或改变整体风格&#xff0c;对于动态调整——特别是图像中主体的位置变化则显得力不从心。这种局限性激发了对更加先进和灵活的图像编辑技术的探索。复旦大学数据科学学院的研究团队提出了一种名为SEELE的…

jmeter-beanshell学习1-vars使用获取变量和设置变量

最近又开始了用jmeter做自动化&#xff0c;不管怎么实现&#xff0c;都逃离不了用beanshell&#xff0c;最后把所有校验都放在了beanshell判断&#xff0c;效果还不错。 首先jmeter有很多beanshell相关的元件&#xff0c;取样器、前置处理器、后置处理器、断言&#xff0c;暂时…

把Windows打造成一个NTP网络时间服务器,为网关提供校时服务

把Windows打造成一个NTP网络时间服务器&#xff0c;为网关提供校时服务。主要目的是为了解决&#xff1a;当网关不能上外网的时候&#xff0c;可以使用局域网的电脑来当做NTP服务器&#xff0c;实现校时功能。 跟着小编来看&#xff0c;如何使用NTP网络时间服务器来同步时间。 …

推荐3款Windows系统的神级软件,免费、轻量、绝对好用!

DiskView DiskView是一款用于管理和查看磁盘空间的工具&#xff0c;它集成了于微软的Windows操作系统资源管理器中&#xff0c;以显示直观的磁盘空间使用情况。该软件通过生成图形化地图&#xff0c;帮助用户组织和管理大量文件和文件夹&#xff0c;从而高效地管理磁盘空间。用…

数字信号处理及MATLAB仿真(2)——离散系统

上回书说到如何来编写一些简单的离散时间序列&#xff0c;今天咱们就来谈谈一些关于常系数差分方程的操作吧。 说到这里咱们对于常系数差分方程可能最关心的就是怎么去求解了。 其中最关键的部分就是filter函数&#xff0c;可以用来计算系统在输入信号为x的输出信号y。大家学过…

【C++】日期类

鼠鼠实现了一个日期类&#xff0c;用来练习印证前几篇博客介绍的内容&#xff01;&#xff01; 目录 1.日期类的定义 2.得到某年某月的天数 3.检查日期是否合法 4.&#xff08;全缺省&#xff09;构造函数 5.拷贝构造函数 6.析构函数 7.赋值运算符重载 8.>运算符重…

elasticsearch-users和elasticsearch-reset-password介绍

elasticsearch 内置 elastic, kibana, logstash_system,beats_system 共4个用户&#xff0c;用途如下&#xff1a; elastic 账号&#xff1a;内置的超级用户&#xff0c;拥有 superuser 角色。 kibana 账号&#xff1a;用来连接 elasticsearch 并与之通信。Kibana 服务器以该用…