SpringBoot+Vue 实现大文件断点下载

目录

  • 效果
  • 代码
    • SpringBoot
    • Vue

效果

步骤

  1. 点击下载 在输入框输入下载的文件名称
  2. 点击暂停
  3. 再次点击开始

SpringBoot+Vue 实现大文件断点下载_第1张图片

SpringBoot+Vue 实现大文件断点下载_第2张图片

下载完成

SpringBoot+Vue 实现大文件断点下载_第3张图片

SpringBoot+Vue 实现大文件断点下载_第4张图片

代码

SpringBoot

pom

     
        
            org.apache.httpcomponents
            httpcore
        
        
            org.apache.httpcomponents
            httpclient
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            commons-io
            commons-io
            2.8.0
        
         
            org.projectlombok
            lombok
            true
        

controller

package com.kang.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

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

/**
 * @Description 文件切片下载
 * @ClassName DownLoadController
 * @Author 康世行
 * @Date 20:58 2023/2/22
 * @Version 1.0
 **/
@Controller
@Slf4j
public class DownLoadController {
    private final static String utf8 = "utf-8";
    @RequestMapping("/down")
    public void downLoadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 设置编码格式
        response.setCharacterEncoding(utf8);
        //获取文件路径
        String fileName=request.getParameter("fileName");
        String drive=request.getParameter("drive");
        //参数校验


        log.info(fileName,drive);
        //完整路径(路径拼接待优化-前端传输优化-后端从新格式化  )
        String pathAll=drive+":\\"+fileName;
        log.info("pathAll{}",pathAll);
        Optional pathFlag = Optional.ofNullable(pathAll);
        File file=null;
        if (pathFlag.isPresent()){
            //根据文件名,读取file流
             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);
            //根据前端传来的Range  判断支不支持分片下载
            response.setHeader("Accept-Range","bytes");
            //获取文件大小
            //response.setHeader("fSize",String.valueOf(fSize));
            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);
           // response.setHeader("Content-Lenght",String.valueOf(rangeLenght));
            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();
            }
        }
    }



}

启动成功
SpringBoot+Vue 实现大文件断点下载_第5张图片

Vue





    
    狂神说Java-ES仿京东实战
    



下载 停止 开始 {{fileFinalOffset}} {{contentList}}

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