springboot 大文件分片上传

news2024/9/23 21:30:35

springboot 大文件分片上传

  • constant
  • entity
  • vo
  • controller
  • utils

在这里插入图片描述

大文件分片上传是一种将大文件分割成多个小文件片段,然后分别上传这些小文件片段的方法。这种方法的好处包括:

  1. 减少重新上传开销:如果网络传输中断,只需重传未上传的部分,而不是整个文件。

  2. 提高灵活性:分片大小可以根据实际情况调整,以平衡上传速度和请求次数。

  3. 支持断点续传:服务器可以记录已经上传的文件块,以便在中断后继续上传。

分片上传的流程大致如下:

  1. 文件分片:首先,对文件进行分片,每个分片的大小可以根据实际情况设定,例如,一个100MB的文件可以分成每个5MB的分片,共20个分片。

  2. 计算MD5值:对每个分片计算MD5值,这有助于文件的完整性校验和唯一标识。(这里使用【文件名+文件后缀+文件大小+时间戳】的方式,对当前文件生成了MD5,用来区分不同的文件,保证文件的唯一性。)

  3. 上传分片:将每个分片和它的MD5值一起上传到服务器。

  4. 服务器校验:服务器接收每个分片并进行校验,确保分片的完整性和正确性。(这里只在文件合并的时候,对文件片数的完整性进行校验。)

  5. 文件合并:当所有分片都成功上传后,服务器将它们合并成完整的文件。

在选择分片大小时,需要权衡请求次数和灵活性。分片太小会增加请求次数和开销,而分片太大则可能减少灵活性。通常,服务器端会有一个固定大小的接收Buffer,分片的大小最好是这个值的整数倍。

此外,前端在开始上传前需要对文件名进行校验,确保文件名不超过最大长度,否则禁止发送请求。

constant

/**
 * 文件上传类型常量类
 **/
public interface FileUploadTypeConstant
{
   

    /**
     * 单文件上传
     */
    String SINGLE = "single";

    /**
     * 分片上传
     */
    String CHUNKS = "chunks";

    /**
     * 文件合并
     */
    String MERGE = "merge";
}

entity

/**
 * @Description 前端统一返回类
 **/
public class ResResult<D>
{
   
    /**
     * 0 为成功,1为失败
     */
    public static final String SUCCESS = "0";
    public static final String FAIL = "1";

    private String code;
    private D data;
    private String msg;

    private ResResult(String code)
    {
   
        this.code = code;
    }

    public static <T> ResResult<T> get(String code)
    {
   
        return new ResResult<>(code);
    }

    public static <T> ResResult<T> success()
    {
   
        return new ResResult<T>(SUCCESS).setMsg("操作成功");
    }

    public static <T> ResResult<T> success(T data)
    {
   
        return new ResResult<T>(SUCCESS).setMsg("操作成功").setData(data);
    }

    public static <T> ResResult<T> success(String msg)
    {
   
        return new ResResult<T>(SUCCESS).setMsg(msg);
    }

    public static <T> ResResult<T> success(String msg, T data)
    {
   
        return new ResResult<T>(SUCCESS).setMsg(msg).setData(data);
    }

    public static <T> ResResult<T> fail()
    {
   
        return new ResResult<T>(FAIL).setMsg("操作失败");
    }

    public static <T> ResResult<T> fail(String msg)
    {
   
        return new ResResult<T>(FAIL).setMsg(msg);
    }

    public static <T> ResResult<T> fail(String msg, T data)
    {
   
        return new ResResult<T>(FAIL).setMsg(msg).setData(data);
    }

    public static <T> ResResult<T> fail(T data)
    {
   
        return new ResResult<T>(FAIL).setMsg("操作失败").setData(data);
    }

    public D getData()
    {
   
        return this.data;
    }

    public ResResult<D> setData(D data)
    {
   
        this.data = data;
        return this;
    }

    public String getCode()
    {
   
        return code;
    }

    public ResResult<D> setCode(String code)
    {
   
        this.code = code;
        return this;
    }

    public String getMsg()
    {
   
        return msg;
    }

    public ResResult<D> setMsg(String msg)
    {
   
        this.msg = msg;
        return this;
    }

    /**
     * 重载空参for 跨服务调用实例化该类用的构造函数
     */
    private ResResult()
    {
   
    }
}

vo

/**
 * 分片文件对象
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileChunkVO
{
   
    /**
     * 文件MD5校验值
     */
    String md5Check;
    /**
     * 当前分片编号
     */
    int chunkNumber;
    /**
     * 总分片数
     */
    int totalChunks;
    /**
     * 文件名称
     */
    String fileName;

    /**
     * single:单文件;
     * chunks:分片;
     * marge:合并
     */
    String type;
}

controller

包括三个方法,分别是:单文件上传,文件分片上传,文件合并。

    /**
     * 文件上传
     *
     * @param fileChunkVO   分片文件对象
     * @return ResResult对象,表示上传结果
     */
    @ApiOperation(value = "文件上传")
    @PostMapping("/upload")
    public ResResult<?> upload(MultipartFile file, FileChunkVO fileChunkVO)
    {
   
        try
        {
   
            switch (fileChunkVO.getType())
            {
   
            case FileUploadTypeConstant.SINGLE:
                List<Map<String, Object>> list = FileUtils.uploadFiles(new MultipartFile[]
                {
    file },

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ZZULI数据结构实验一】多项式的三则运算

【ZZULI数据结构实验一】多项式的四则运算 ♋ 结构设计♋ 方法声明♋ 方法实现&#x1f407; 定义一个多项式类型并初始化---CreateDataList&#x1f407; 增加节点---Getnewnode&#x1f407; 打印多项式类型的数据-- PrintPoly&#x1f407; 单链表的尾插--Listpush_back&…

Bert基础(七)--Bert实战之理解Bert模型结构

在篇我们将详细学习如何使用预训练的BERT模型。首先&#xff0c;我们将了解谷歌对外公开的预训练的BERT模型的不同配置。然后&#xff0c;我们将学习如何使用预训练的BERT模型作为特征提取器。此外&#xff0c;我们还将探究Hugging Face的Transformers库&#xff0c;学习如何使…

【机器学习】引领未来的力量:技术革新与应用探索

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟。提供嵌入式方向的学习指导、简历面…

nodejs中使用@maxmind/geoip2-node 查询地理位置信息

介绍 maxmind/geoip2-node 是一个Node.js模块&#xff0c;用于与MaxMind的GeoIP2数据库进行交互&#xff0c;从而获取IP地址的地理位置信息。MaxMind的GeoIP2数据库包含了全球范围内的IP地址和对应的地理位置信息&#xff0c;如国家、城市、经纬度等。使用maxmind/geoip2-node…

利用sin/cos原理驱动步进电机

利用sin/cos原理控制步进电机转动 前言什么是步进电机驱动器细分控制电机内部结构图片步进电机驱动原理&#xff08;重要&#xff09;步进电机参数&#xff11;、步距角&#xff1a;收到一个脉冲转动的角度&#xff12;、细分数 &#xff1a;&#xff11;&#xff0f;&#xf…

M1 mac安装 Parallels Desktop 18 激活

M1 mac安装 Parallels Desktop 18 激活 下载安装Parallels Desktop 18.1.1 (53328) 激活1. 拷贝prl_disp_service2. 在终端打开Crack所在位置3. 输入命令&#xff0c;激活成功 下载 安装包和激活文件下载地址 链接: https://pan.baidu.com/s/1EjT7xeEDcntIIoOvvhBDfg?pwd9pue …

Kubernetes Pod深度解析:构建可靠微服务的秘密武器(上)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Kubernetes概述 2、Pod概述 二、Po…

AI老人跌倒监测报警摄像机

AI老人跌倒监测报警摄像机是一种基于人工智能技术的智能监控设备&#xff0c;专门用于监测老年人的跌倒情况并提供实时报警功能&#xff0c;以及时处理紧急情况&#xff0c;保障老人安全。这种摄像机利用先进的AI算法和深度学习技术&#xff0c;能够实时监测老人的行为&#xf…

时序信号高低频分析——经验模态分解EMD

时序信号高低频分析——经验模态分解EMD 介绍 经验模态分解&#xff08;Empirical Mode Decomposition&#xff0c;EMD&#xff09;是一种用于时序信号分解的自适应方法&#xff0c;旨在将原始信号分解为多个固有模态函数&#xff08;Intrinsic Mode Functions&#xff0c;IM…

【c++】类和对象(二)this指针

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本节内容来到类和对象第二篇&#xff0c;本篇文章会带领大家了解this指针 目录 1.this指针1.1this指针的引出1.2this指针的特性1.3思考题1.4C语言和C实现Stack的对…

RWTH-PHOENIX Weather数据集模型说明和下载

RWTH-PHOENIX Weather 2014 T数据集说明: 德国公共电视台PHOENIX在三年内(2009 年至 2011 年) 录制了配有手语翻译的每日新闻和天气预报节目,并使用注释符号转录了 386 个版本的天气预报。 此外,我们使用自动语音识别和手动清理来转录原始德语语音。因此,该语料库允许训练…

近线数仓优化改造

近线数仓优化改造 1. 背景2. 优化3. 改造3.1. 重构3.2. 优化 1. 背景 大概就是有那么一个数仓&#xff0c;然后简略结构如下&#xff1a; #mermaid-svg-PVoUzuQhj2BK7Qge {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid…

【C语言】动态内存管理及其常见错误

文章目录 1、前言&#xff1a;为什么要有动态内存分布2、三种动态内存的创建方式及其释放2.1 malloc2.2 calloc2.3 ralloc2.4 free 3、常⻅的动态内存的错误3.1 对NULL指针的解引用操作3.2 对动态开辟空间的越界访问3.3 对非动态开辟内存使用free释放3.4 使⽤free释放⼀块动态开…

C++动态内存管理:new/delete与malloc/free的对比

在C中&#xff0c;动态内存管理是一个至关重要的概念。它允许我们在程序运行时根据需要动态地分配和释放内存&#xff0c;为对象创建和销毁提供了灵活性。在C中&#xff0c;我们通常会用到两对工具&#xff1a;new/delete 和 malloc/free。虽然它们都能够完成类似的任务&#x…

2月线上速溶咖啡行业数据分析:“减肥咖啡”引领电商新潮流

随着生活节奏的加快&#xff0c;速溶咖啡因其便捷性受到广大消费者的青睐。不过&#xff0c;在如今世界咖啡市场激烈竞争的情况下&#xff0c;中国速溶咖啡市场也受到影响&#xff0c;增速有所放缓。 根据鲸参谋电商数据平台显示&#xff0c;2月线上综合电商&#xff08;京东天…

003_vector_conventions_in_MATLA中的向量约定

MATLAB中的向量约定 1. 前言 MATLAB是一种用于数值计算和数据可视化的高级编程语言。以前&#xff0c;都不好意思说它是编程语言&#xff0c;它实际上只是一个脚本工具&#xff0c;配套了一堆工具箱。比如Simulink&#xff0c;可以开展非常复杂的仿真&#xff0c;还能编译到实…

海外媒体发稿:出口贸易媒体发稿7个秘籍揭晓-华媒舍

出口贸易是许多国家经济增长的关键驱动力之一。不仅可以加快国家的发展步伐&#xff0c;还能为企业创造巨大的商机。如何能够在出口贸易中取得成功&#xff0c;如何能够引起媒体的关注&#xff0c;成为企业广告和宣传的焦点&#xff0c;是许多出口企业面临的挑战。本文将揭示出…

【LeetCode热题100】108. 将有序数组转换为二叉搜索树(二叉树)

一.题目要求 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡二叉搜索树。 二.题目难度 简单 三.输入样例 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#x…

【Java程序设计】【C00367】基于(JavaWeb)Springboot的粮仓管理系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

JVM——字符串常量池

在Java程序中String类的使用几乎无处不在&#xff0c;String类代表字符串&#xff0c;字符串对象可以说是Java程序中使用最多的对象了。首先&#xff0c;在Java中创建大量对象是非常耗费时间的。其次&#xff0c;在程序中又经常使用相同的字符串对象&#xff0c;如果每次都去重…