断点续传(上传)Java版

发布时间 2023-10-12 10:05:14作者: Xproer-松鼠

1. 客户每次上传前先获取一下当前文件已经被服务器接受了多少

2. 上传时设定偏移量,跳过服务器已收到的长度

@SpringBootTest
public class FileTests {

    @Test
    void seekTest() {
        try {
            RandomAccessFile writeFile = new RandomAccessFile("D:\\temp\\1.txt", "rw");
            writeFile.seek(2);
            writeFile.write("-VipSoft-".getBytes());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
package com.vipsoft.api;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.vipsoft.api.base.util.ApiResult;
import com.vipsoft.api.base.util.BuinessCodeEnum;
import com.vipsoft.api.base.util.PojoUtil;
import com.vipsoft.api.base.vo.UploadFileModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 断点续传
 */
@Api(tags = "断点续传接口")
@RestController
@RequestMapping("/upload")
public class UploadController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    String savePath = "D:\\temp\\UpdateSystem"; //TODO 配置文件

    /**
     * 获取已上传文件大小
     * @param request
     * @param param
     * @return
     */
    @ApiOperation(value = "获取已上传文件大小", notes = "")
    @PostMapping("/getFileLength")
    public ApiResult getFileLength(HttpServletRequest request, @RequestBody UploadFileModel param) {
        //判断入参是否为空
        ApiResult result = new ApiResult();
        try {
            String fileName = "";
            if (param != null) {
                fileName = param.getFileName();
            }
            if (StrUtil.isEmpty(fileName)) {
                //实体没有就从Header 里面取
                fileName = request.getHeader("FileName");
            }
            if (StrUtil.isEmpty(fileName)) {
                result.setBussinessCode(6001);
                ;
                result.setBussinessMsg("FileName 文件名不能为空");
                result.setBussinessData(0);
                return result;
            }
            //设置文件存放路径
            //string dir = HttpContext.Current.Server.MapPath(SavePath);
            fileName = savePath + "\\" + fileName;
            String msg = "";
            if (FileUtil.exist(fileName)) {
                File file = new File(fileName);
                result.setBussinessData(file.length());
                msg = StrUtil.indexedFormat("FileName => {0} Length => {1}", fileName, file.length());
            } else {
                result.setBussinessData(0);
                msg = StrUtil.indexedFormat("文件不存在 FileName => {0} Length => 0", fileName);
            }
            result.setBussinessMsg("获取成功!");
            result.setBussinessCode(0);
            msg = StrUtil.indexedFormat("文件不存在 FileName => {0} Length => 0", fileName);
            logger.info("获取文件长度 => {}", msg);

        } catch (Exception ex) {
            logger.error(PojoUtil.pojoToJson(param));
            logger.error(ex.getMessage(), ex);
            result.setBussinessCode(BuinessCodeEnum.ERROR.getCode());
            result.setBussinessMsg(ex.getMessage());
        }
        return result;
    }

    /**
     * 上传文件
     * @param request
     * @return
     */
    @ApiOperation(value = "获取已上传文件大小", notes = "")
    @PostMapping("/uploadFile")
    public ApiResult uploadFile(HttpServletRequest request, @RequestParam(value = "File") MultipartFile file) {
        //判断入参是否为空
        ApiResult result = new ApiResult();
        String fileName = "";
        try {
            fileName = request.getParameter("FileName");
            long offset = 0;
            String offsetStr = request.getHeader("Offset");
            if (StrUtil.isEmpty(offsetStr)) {
                offsetStr = request.getParameter("Offset");
            }
            if (StrUtil.isNotEmpty(offsetStr)) {
                offset = Long.valueOf(offsetStr);
            }
            if (StrUtil.isEmpty(fileName)) {
                logger.error("FileName 上传文件名不能为空");
                result.setBussinessCode(6002);
                result.setBussinessMsg("FileName 上传文件名不能为空");
                result.setBussinessData(false);
                return result;
            }
            File dir = new File(savePath);
            //如果不存在文件夹,就创建文件夹
            if (!dir.exists()) {
                dir.mkdir();
            }
            String saveFileName = savePath + "\\" + fileName;
            RandomAccessFile writeFile = new RandomAccessFile(saveFileName, "rw");
            writeFile.seek(offset);

            String ss = file.getName();

            long upLoadLength = file.getSize();
            writeFile.write(file.getBytes());

            result.setBussinessCode(0);
            result.setBussinessMsg("上传成功!");
            result.setBussinessData(true);

            logger.info("上传文件 {} Offset => {} File.ContentLength => {} => {}", fileName, offset, upLoadLength, saveFileName);
        } catch (IOException e) {
            result.setBussinessCode(6003);
            result.setBussinessMsg(e.getMessage());
            result.setBussinessData(false);
            logger.error(e.getMessage() + " => " + fileName, e);
        }
        return result;
    }

}
public class UploadFileModel implements Serializable {

    @JsonProperty("FileName")
    private String fileName;

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
 
 

参考文章:http://blog.ncmem.com/wordpress/2023/10/12/%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0%ef%bc%88%e4%b8%8a%e4%bc%a0%ef%bc%89java%e7%89%88/

欢迎入群一起讨论