Vue、Springboot 大文件分片下载、多线程下载

9,194次阅读
没有评论

共计 5521 个字符,预计需要花费 14 分钟才能阅读完成。

大文件分片下载

解决大文件上传超时问题,使用 Range 支持,对文件进行分片下载
步骤:
一、首先通过发送 0 - 1 长度去后端获取文件大小、名称等信息返回给前端
二、前端通过文件大小、分片大小计算出分片数据量,循环请求后端,分片获取文件数据,前端组合 Blob 数组数据,记录当前请求的索引和数据进行组合
三、全部异步请求完毕之后,对所有数据进行从大到小排序,从新生成一个新的 Blob, 一定要保证数组的顺序正确,不然打开文件会有异常
Vue、Springboot 大文件分片下载、多线程下载

多线程异步下载






to 工具类


export default function to (promise) {
  if (!promise || !Promise.prototype.isPrototypeOf(promise)) {
    return new Promise((resolve, reject) => {
      reject(new Error(`${promise}rn requires promises as the param"`))
    }).catch((err) => {
      return [err, null]
    })
  }
  return promise.then(data => {
    return [null, data]
  }).catch(err => [err])
}

Java 后端代码

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Optional;


@RequestMapping("/download")
@RestController
@Api(tags = "文件下载")
@Slf4j
public class DownLoadController {

    private final static String utf8 = "utf-8";

    @GetMapping("/file")
    public void downLoadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        response.setCharacterEncoding(utf8);
        
        String drive = "F";
        String fileName = "AdobeAcrobatProDC_setup.zip";
        


        log.info(fileName, drive);
        
        String pathAll = drive + ":" + fileName;
        log.info("pathAll{}", pathAll);
        OptionalString> pathFlag = Optional.ofNullable(pathAll);
        File file = null;
        if (pathFlag.isPresent()) {
            
            file = new File(pathAll);
            log.info("文件路径是{}", pathAll);
            if (!file.exists()) {
                log.warn("文件不存在");
                return;
            }
        } else {
            
            log.warn("请输入文件名!");
            return;
        }

        InputStream is = null;
        OutputStream os = null;
        try {
            
            long fSize = file.length();
            response.setContentType("application/x-download");
            String file_Name = URLEncoder.encode(file.getName(), "UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            response.setHeader("Accept-Range", "bytes");
            
            response.setHeader("fName", file_Name);
            
            long pos = 0, last = fSize - 1, sum = 0;
            
            if (null != request.getHeader("Range")) {
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                String numRange = request.getHeader("Range").replaceAll("bytes=", "");
                String[] strRange = numRange.split("-");
                if (strRange.length == 2) {
                    pos = Long.parseLong(strRange[0].trim());
                    last = Long.parseLong(strRange[1].trim());
                    
                    if (last > fSize - 1) {
                        last = fSize - 1;
                    }
                } else {
                    
                    pos = Long.parseLong(numRange.replaceAll("-", "").trim());
                }
            }
            long rangeLenght = last - pos + 1;
            String contentRange = new StringBuffer("bytes").append(pos).append("-").append(last).append("/").append(fSize).toString();
            response.setHeader("Content-Range", contentRange);
            os = new BufferedOutputStream(response.getOutputStream());
            is = new BufferedInputStream(new FileInputStream(file));
            
            is.skip(pos);
            byte[] buffer = new byte[1024];
            int lenght = 0;
            
            while (sum  rangeLenght) {
                lenght = is.read(buffer, 0, (rangeLenght - sum)  buffer.length ? (int) (rangeLenght - sum) : buffer.length);
                sum = sum + lenght;
                os.write(buffer, 0, lenght);
            }
            log.info("下载完成");
        } finally {
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
        }
    }
}

原文地址: Vue、Springboot 大文件分片下载、多线程下载

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-23发表,共计5521字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)