【SpringBoot】文件分片上传、合并

背景

在上传大型文件时,一般采用的都是分片、断点续传等技术,这样不会导致因文件过大而造成系统超时或者过压等情况。

 接下来我们进入教学

如果有帮助到您,麻烦请点击个收藏、赞,谢谢~

【SpringBoot】文件分片上传、合并_第1张图片

一、实际效果图

整个前端网页的效果图:

【SpringBoot】文件分片上传、合并_第2张图片

二、后端代码

1.开发环境

开发工具:idea  ,开发语言:java  ,框架:springboot

2.创建文件上传工具类

创建工具类:FileUtils


import com.caozhen.common.constant.HttpStatusConstant;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;


/**
 * @author caozhen
 * @ClassName FileUtils
 * @description: 文件上传
 * @date 2023年10月07日
 * @version: 1.0
 */
@Component
public class FileUtils {
    //文件路径,可以统一配置
    private static final String UPLOAD_DIR = "d:\\uploads";

    /***
     * 断点续传(上传文件)
     * @param file
     * @return
     */
    public ResultAjax resumeFile(MultipartFile file,
                                 int chunkNumber,
                                 int totalChunks,
                                 String identifier) {
        try {
            File uploadDir = new File(UPLOAD_DIR);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            String fileName = identifier + "-chunk-" + chunkNumber;
            File chunkFile = new File(uploadDir, fileName);

            try (InputStream inputStream = file.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(chunkFile)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }

            if (chunkNumber == totalChunks - 1) {
                File finalFile = new File(UPLOAD_DIR + File.separator + identifier);
                for (int i = 0; i < totalChunks; i++) {
                    File part = new File(uploadDir, identifier + "-chunk-" + i);
                    try (FileInputStream partStream = new FileInputStream(part);
                         FileOutputStream finalStream = new FileOutputStream(finalFile, true)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = partStream.read(buffer)) != -1) {
                            finalStream.write(buffer, 0, bytesRead);
                        }
                    }
                    part.delete();
                }
                uploadDir.delete();
            }

            return ResultAjax.ok("Chunk " + chunkNumber + " uploaded");
        } catch (IOException e) {
            e.printStackTrace();
            return ResultAjax.error(HttpStatusConstant.HTTP_CODE_500, "上传失败:" + e.getMessage());
        }
    }
}

3.创建controller类

@RestController
@Slf4j
@Api(tags = "系统服务")
@RequestMapping("/sys/test/")
public class SystemController {
  
    @Autowired
    private FileUtils fileUtils;


    @ApiOperation("测试文件断点续传-上传")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResultAjax fileUploads(@RequestParam("file") MultipartFile file,
                                  @RequestParam("chunkNumber") int chunkNumber,
                                  @RequestParam("totalChunks") int totalChunks,
                                  @RequestParam("identifier") String identifier) {
        return fileUtils.resumeFile(file,chunkNumber,totalChunks,identifier);
    }

}

4.自定义封装类ResultAjax


import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author caozhen
 * @ClassName ResultAjax
 * @description: 全局封装统一返回实体类
 * @date 2023年07月26日
 * @version: 1.0
 */
public class ResultAjax extends LinkedHashMap {
    private static final long serialVersionUID = 1L;

    public ResultAjax() {
        put("success", true);
        put("code", HttpStatusConstant.HTTP_CODE_200);
        put("msg", "操作成功!");
        put("data", null);
    }

    public ResultAjax(Integer code) {
        put("success", true);
        put("code", code);
        put("msg", "操作成功!");
        put("data", null);
    }

    public ResultAjax(Integer code, String msg) {
        put("success", true);
        put("code", code);
        put("msg", msg);
        put("data", null);
    }

    public static ResultAjax error() {
        return error(HttpStatusConstant.HTTP_CODE_500, "未知异常,请联系管理员");
    }

    public static ResultAjax errorDebug(String message) {
        return error(HttpStatusConstant.HTTP_CODE_500, "未知异常 " + message + ",请联系管理员");
    }

    public static ResultAjax error(String msg) {
        return error(HttpStatusConstant.HTTP_CODE_500, msg);
    }


    public static ResultAjax error(int code, String msg) {
        ResultAjax r = new ResultAjax();
        r.put("success", false);
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public ResultAjax errorInfo(String msg) {
        this.put("errorMsg", msg);
        return this;
    }

    public static ResultAjax ok(Object data) {
        ResultAjax r = new ResultAjax();
        r.put("success", true);
        r.put("code", HttpStatusConstant.HTTP_CODE_200);
        r.put("msg", "操作成功!");
        r.put("data", data);
        return r;
    }

    public static ResultAjax ok(Map map) {
        ResultAjax r = new ResultAjax();
        r.putAll(map);
        r.put("data", null);
        return r;
    }

    public static ResultAjax ok(String msg, Integer code) {
        ResultAjax r = new ResultAjax();
        r.put("success", true);
        r.put("code", code);
        r.put("msg", msg);
        r.put("data", null);
        return r;
    }

    public static ResultAjax ok() {
        return new ResultAjax().put("msg", "操作成功!").put("data", null);
    }

    public static ResultAjax ok(Integer size) {
        return new ResultAjax().put("data", null);
    }

    @Override
    public ResultAjax put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    /**
     * 添加返回结果数据
     *
     * @param key
     * @param value
     * @return
     */
    public ResultAjax putData(String key, Object value) {
        Map map = (HashMap) this.get("data");
        map.put(key, value);
        return this;
    }
}
public class HttpStatusConstant {
    //目前常用的,200,500
    public final static Integer HTTP_CODE_200 = 200;
    public final static Integer HTTP_CODE_500 = 500;
    //拦截
    public final static Integer HTTP_CODE_403 = 403;
    public final static Integer HTTP_CODE_401 = 401;
}

三、前端代码




    文件分片上传


    
    
    
    
    0%
    
    


四、接下来我们演示下

五、留言区

有什么问题可以在底下评论区留言,看到会在本文后追加回复!

 

你可能感兴趣的:(SpringBoot,spring,boot,后端,java)